C++ 多线程 学习笔记(二)
来源:互联网 发布:mac 虚拟光驱软件 编辑:程序博客网 时间:2024/06/09 19:12
进程:基于进程的多任务处理是程序的并发执行。
线程:基于线程的多任务处理是同一程序的片段的并发执行。
C++ 多线程写法,从入门开始,一点点往下写,我也不知道能学到精通还是到放弃。
根据主流的一些博客技术文档,循序渐进,适于新手入门。
首先第一个程序是直接使用多线程创建函数创建多个线程。
编译的时候需要静态链接库文件pthread ,使用命令 g++ -o target target.cpp -lpthread 其中-lpthread 编译选项到位置可任意,
#include <pthread.h>#include <iostream>using namespace std;#define NUM_THREADS 5void* say_hello(void* args)//必须使用指针,因为线程创建函数这样要求的。{ cout << "Hello thread !" << endl;}int main(){ // 定义线程的 id 变量,多个变量使用数组 pthread_t tids[NUM_THREADS]; for(int i = 0; i < NUM_THREADS; ++i) { //参数依次是:创建的线程id,线程参数,调用的函数,传入的函数参数 int ret = pthread_create(&tids[i], NULL, say_hello, NULL); if (ret != 0) { cout << "pthread_create error: error_code=" << ret << endl; } } //等各个线程退出后,进程才结束,否则进程强制结束了,线程可能还没反应过来; pthread_exit(NULL);}
注意: pthread_exit()函数会直接导致整个main函数结束。感觉上相当于return。
运行结果为:
Hello thread !Hello thread !Hello thread !Hello thread !Hello thread !
然后改动一下 ,我们在主函数中进行循环输出,循环创建新的线程,每个线程中也需要有输出。相关代码如下:
#include <iostream>#include <cstdlib>#include <pthread.h>using namespace std;#define NUM_THREADS 5void *PrintHello(void *threadid){ //因为pthread_create()函数只接受void类型,因此需要对传入的参数再次进行强制类型转换,由无类型指针变为整形数指针,然后再读取 int tid = *((int*)threadid); cout << "Hello thread! 来自线程" << tid << endl; pthread_exit(NULL);}int main (){ pthread_t threads[NUM_THREADS]; int indexes[NUM_THREADS];// 用数组来保存i的值 int rc; int i; for( i=0; i < NUM_THREADS; i++ ){ cout << "main() : 创建的线程" << i << endl; indexes[i] = i; //先保存i的值 // 传入的时候必须强制转换为void* 类型,即无类型指针 rc = pthread_create(&threads[i], NULL, PrintHello, (void *)&(indexes[i])); if (rc){ cout << "Error:无法创建线程," << rc << endl; exit(-1); } } pthread_exit(NULL);}编译的时候命令为:
g++ -o test1 test1.cpp -lpthread运行三次 结果分别为:
main() : 创建的线程0main() : 创建的线程1Hello thread! 来自线程0main() : 创建的线程2Hello thread! 来自线程1main() : 创建的线程3Hello thread! 来自线程2main() : 创建的线程4Hello thread! 来自线程3Hello thread! 来自线程4
main() : 创建的线程0main() : 创建的线程1Hello thread! 来自线程0main() : 创建的线程2Hello thread! 来自线程1main() : 创建的线程3Hello thread! 来自线程2main() : 创建的线程4Hello thread! 来自线程3Hello thread! 来自线程4
main() : 创建的线程0main() : 创建的线程1main() : 创建的线程2Hello thread! 来自线程1main() : 创建的线程3Hello thread! 来自线程0Hello thread! 来自线程2main() : 创建的线程4Hello thread! 来自线程3Hello thread! 来自线程4可以发现,并没有一定的顺序和规律。
稍作调整,加入 pthread_join()函数,相关介绍为 “代码中如果没有pthread_join主线程会很快结束从而使整个进程结束,从而使创建的线程没有机会开始执行就结束了。加入pthread_join后,主线程会一直等待直到等待的线程结束自己才结束,使创建的线程有机会执行。”所以将代码更改如下为:
#include <cstdlib>#include <pthread.h>using namespace std;#define NUM_THREADS 5 void *PrintHello(void *threadid){ //因为pthread_create()函数只接受void类型,因此需要对传入的参数再次进行强制类型转换,由无类型指针变为整形数指针,然后再读取 int tid = *((int*)threadid); cout << "Hello thread! 来自线程" << tid << endl; pthread_exit(NULL);}int main (){ pthread_t threads[NUM_THREADS]; int indexes[NUM_THREADS];// 用数组来保存i的值 int rc; int i; for( i=0; i < NUM_THREADS; i++ ){ cout << "main() : 创建的线程" << i << endl; indexes[i] = i; //先保存i的值 // 传入的时候必须强制转换为void* 类型,即无类型指针 rc = pthread_create(&threads[i], NULL, PrintHello, (void *)&(indexes[i])); if (rc){ cout << "Error:无法创建线程," << rc << endl; exit(-1); }pthread_join( threads[i], NULL ); }}
在循环中加入join函数,会使程序运行变得有序。因此,运行结果为:main() : 创建的线程0Hello thread! 来自线程0main() : 创建的线程1Hello thread! 来自线程1main() : 创建的线程2Hello thread! 来自线程2main() : 创建的线程3Hello thread! 来自线程3main() : 创建的线程4Hello thread! 来自线程4总结一下:
基于以上代码主要学习了pthread_t 表示线程标识符,pthread_create()函数用来进行线程的创建,pthread_exit()函数进行所有的线程的终止。pthread_join()函数进行线程的阻塞,保证在主线程结束之前所有创建的新的线程按照循环的顺序执行。
阅读全文
0 0
- 多线程学习笔记(二)
- 学习笔记(二)多线程
- 多线程学习笔记(二)
- 多线程学习笔记 二
- 多线程学习笔记二
- Linux C 多线程编程学习(二)
- 多线程编程学习笔记(二)
- VC多线程编程学习笔记(二)
- 多线程多任务学习笔记(二)
- Posix多线程编程学习笔记(二)
- java学习笔记(二)多线程
- Java多线程学习笔记(二)
- Java多线程学习笔记(二)
- C++ 多线程 学习笔记(二)
- Java多线程学习笔记(二)
- java多线程学习笔记(二)
- c++ 多线程学习笔记(二)
- c学习笔记(二)
- (初学者)求最大公约数与最小公倍数之穷举法
- 使用curator进行选举
- TCO之旅
- Java web Filter, Strurs2 Interceptor 和 SpringMVC Interceptor 三者之间的联系与区别
- jqgrid treegrid 重新加载数据
- C++ 多线程 学习笔记(二)
- url管理器
- Set 一(TreeSet与HashSet)十四
- 深度学习笔记——深度学习框架TensorFlow之Model(十三)
- HttpURLConnection上传大文件内存溢出问题
- 数字证书及CA的扫盲介绍
- HTML学习笔记<5>[CSS]
- 面试编程题:单例模式singleton
- golang下载支付宝对账单