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()函数进行线程的阻塞,保证在主线程结束之前所有创建的新的线程按照循环的顺序执行。








原创粉丝点击