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;

}
posted @ 2025-05-19 22:55  北燃  阅读(29)  评论(0)    收藏  举报