C++ 进阶 day14多线程编程
多线程编程
由于C库没有提供有关多线程的相关操作,对于多线程编程要依赖于第三方库
头文件:
#include<pthread.h>
编译时:需要加上 -lpthread 选项,链接上对于的线程支持库
创建线程
基本函数介绍
#include <pthread.h> //头文件
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *
(*start_routine) (void *), void *arg);
-
功能:创建分支线程
-
参数1:线程号,通过参数返回,用法:在外部定义一个该类型的变量,将地址传递入函数,调用结束后,变量值是线程编号
-
参数2:线程属性,一般填NULL,让系统使用默认属性创建一个线程
-
参数3:是一个调回函数,一个函数指针,需要向该参数中传递一个函数名,作为线程体执行函数,该函数由用户自己定义,参数是void*类型,返回值也是void *类型
-
参数4:是参数3的参数,如果不想向线程体内传递数据,填NULL即可
-
返回值:成功返回0,失败返回一个错误码(非linux内核的错误码,是线程支持库中定义的一个错误码)
-
Compile and link with -pthread. //编译时需要加上 -pthread选项
案例1
不向线程体传递数据
点击查看代码
#include <myhead.h>
void *task(void *arg){
while(1){
printf("我是分支线程\n");
sleep(1);
}
}
int main(int argc,const char *argv[]){
pthread_t tid=-1;//用于存储线程号的变量
if(pthread_create(&tid,NULL,task,NULL)!=0){
//参数2:表示让系统使用默认属性创建一个线程
//参数3:线程函数名
//参数4:表示向线程体中传递的数据
printf("tid create error\n");
return -1;
}
printf("pthread_create success\n");
while(1){
printf("我是主线程\n");
sleep(1);
}
while(1);//防止主线程结束
}
案例2
向线程体中传递单个数据
点击查看代码
#include <myhead.h>
void *task(void *arg){
//arg-->&num 但是arg是一个void*类型的变量,需要转换为具体指针进行操作
//(int*)arg -->将其转换为整型的指针
//*(int *)arg -->num的值
int key=*(int *)arg;
printf("我是分支线程:num = %d\n",key);//1314
}
int main(int argc,const char *argv[]){
pthread_t tid=-1;
int num=520;
if(pthread_create(&tid,NULL,task,&num)!=0){
//参数2:表示让系统使用默认属性创建一个线程
//参数3:线程体函数名
//参数4:表示像线程体传递的数据
printf("tid create error\n");
return -1;
}
printf("pthread_create success,tid = %#lx\n",tid);
printf("我是主线程\n");
num=1314;
printf("主线程中num = %d\n",num);
while(1);//防止主线程结束
return 0;
}
案例3
向线程体传入多个数据
点击查看代码
#include <myhead.h>
struct Info{
int num;
char name[20];
double score;
};
void *task(void *arg){
Info buf=*((Info*)arg);//将结构体指针转换为结构体变量
printf("分支线程中:num = %d,name = %s,score = %.2lf\n",buf.num,buf.name,buf.score);
}
int main(int argc,const char *argv[]){
pthread_t tid=-1;
int num=520;
char name[20]="zhangsan";
double score=99.5;
//需求:将上面的三个数据全部传入线程体中
Info buf ={num,"zhangsan",score};
if(pthread_create(&tid,NULL,task,&buf)!=0){
//参数2:表示让系统使用默认属性创建一个线程
//参数3:线程函数体
//参数4:表示向线程体中传递的数据
{
printf("tid create error\n");
return -1;
}
}
printf("pthread_create success,tid = %#lx\n",tid);
printf("我是主线程\n");
while(1);//防止主线程结束
return 0;
}
线程号的获取:pthread_self
#include <pthread.h>
pthread_t pthread_self(void);
- 功能:获取当前线程的线程号
- 参数:无
- 返回值:返回调用线程的id号,不会失败
线程的退出函数:pthread_exit
#include <pthread.h>
void pthread_exit(void *retval);
- 功能:退出当前线程
- 参数:表示退出时的状态,一般填NULL
- 返回值:无
线程的资源回收:pthread_join
#include <pthread.h>
int pthread_join(pthread_t thread, void **retval);
- 功能:阻塞回收指定线程的资源
- 参数1:要回收的线程线程号
- 参数2:线程退出时的状态,一般填NULL
- 返回值:成功返回0,失败返回一个错误码
线程分离态:pthread_detach
#include <pthread.h>
int pthread_detach(pthread_t thread);
- 功能:将指定线程设置成分离态,被设置成分离态的线程,退出后,资源由系统自动回收
- 参数:要分离的线程号
- 返回值:成功返回0,失败返回一个错误码
点击查看代码
#include <myhead.h>
void *task(void *arg){
printf("分支线程,tid = %#x\n",pthread_self());//2.调用函数输出当前的线程的线程号
sleep(5);
//3.退出线程
pthread_exit(NULL);
}
int main(){
//1.定义一个线程号变量
pthread_t tid=-1;
//创建一个线程
if(pthread_create(&tid,NULL,task,NULL)!=0){
printf("pthread_create error\n");
return -1;
}
printf("主线程,tid = %#x\n",tid);
//4.回收分支线程的资源
//pthread_join(tid,NULL);//前三秒,主线程处于休眠等待分支线程的结束
//分支线程处于休眠状态
//将线程设置成为离态
pthread_detach(tid);
sleep(5);
//while(1); //防止主线程结束
std::cout<<"Hello,world"<<std::endl;
return 0;
}

浙公网安备 33010602011771号