线程相关函数/设置线程分离属性

本文详细介绍了Linux C++中的线程函数,包括pthread_create用于创建线程,pthread_exit让线程退出,pthread_join等待线程结束,pthread_detach设置线程分离属性,以及pthread_cancel取消线程。重点讨论了线程的内存共享问题,线程分离的资源回收,以及线程取消的非实时性。
摘要由CSDN通过智能技术生成

pthread_create()函数

函数作用

创建一个线程

函数原型

int pthread_create(pthread_t *thread,
const pthread_attr_t *attr,
void *(*start_routine) (void *),
void *arg);
返回值:
成功:返回0
失败:返回错误号

函数参数:

pthread_t:传出参数,保存系统为我们分配好的线程ID

当前Linux中可理解为:typedef unsigned long int pthread_t。

attr:通常传NULL,表示使用线程默认属性。若想使用具体属性也可以修改该参数。

start_routine:函数指针,指向线程主函数(线程体),该函数运行结束,则线程结束。(一般是一个自定义函数)

arg:线程主函数执行期间所使用的参数。

注意点

由于pthread_create的错误码不保存在errno中,因此不能直接用perror()打印错误信息,可以先用strerror()把错误码转换成错误信息再打印。

如果任意一个线程调用了exit或_exit,则整个进程的所有线程都终止,由于从main函数return也相当于调用exit,为了防止新创建的线程还没有得到执行就终止,我们在main函数return之前延时1秒,这只是一种权宜之计,即使主线程等待1秒,内核也不一定会调度新创建的线程执行,如果主线程调用pthread_exit函数也不会使整个进程退出,不影响其他线程的执行。

[例子] : 主线程循环创建5个子线程,并让子线程判断自己是第几个子线程

#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>
#include<string.h>
#Include<pthread.h>
void *myptread(void *arg)
{
	int x=*(int *)arg;
	printf("[%d]:child thread,pid==[%d],id==[%ld]\n",i,getpid(),pthread_self());
}	

int main()
{
	pthread_t thread[5];
	int i;
	for(i=0;i<5;i++)
	{
		int ret = pthread_create(&thread[1],NULL,mypthread,&i);
		if(ret!=0)
		{
			printf("pthread_create error\n",strerror(ret));
			return -1;
		}
	}
	printf("main thread,pid==[%d],id==[%ld]\n",getpid(),pthread_self());
	sleep(1);
	return 0;

在这里插入图片描述
是由于主线程可能会在一个cpu时间片内连续创建了5个子线程,此时变量i的值变成了5,当主线程失去cpu的时间片后,子线程得到cpu的时间片,子线程访问的是变量i的内存空间的值,所以打印出来值为5.
在这里插入图片描述
主线程和子线程共享同一块内存空间

在这里插入图片描述

主线程和子线程分时使用cpu资源

解决办法:不能使多个子线程都共享同一块内存空间,应该使每个子线程访问不同的内存空间,可以在主线程定义一个数组:int arr[5];,然后创建线程的时候分别传递不同的数组元素,这样每个子线程访问的就是互不相同的内存空间,这样就可以打印正确的值。
如下图:
在这里插入图片描述

pthread_exit()函数

在线程中禁止调用exit函数,否则会导致整个进程退出,取而代之的是调用pthread_exit函数,这个函数是使一个线程退出,如果主线程调用pthread_exit函数也不会使整个进程退出,不影响其他线程的执行。

函数作用

将单个线程退出

函数原型

void pthread_exit(void *retval);

函数参数

retval表示线程退出状态,通常传NULL

另注意,pthread_exit或者return返回的指针所指向的内存单元必须是全局的或者是用malloc分配的,不能在线程函数的栈上分配,因为当其它线程得到这个返回指针时线程函数已经退出了,栈空间就会被回收。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<unistd.h>
#include<pthread.h>

int g_var = 0;
void *mythread(void *arg){
	printf("child thread,pid == [%d], id==[%ld]\n",getpid(),pthread_self());
	pthread_exit(NULL);
}
int main(){
	pthread_t thread;
	int ret = pthread_create(&thread, NULL, mythread, NULL);
	if(ret != 0){
	printf("pthread_create error,[%s]\n", strerror(ret));
	return -1;
	}
	printf("main thread, pid ==[%d],id == [%ld]\n", getpid(), pthread_self());
	
	sleep(1);
	return 0;
}

在这里插入图片描述

pthread_join()函数

函数描述:

阻塞等待线程退出,获取线程退出状态。其作用,对应进程中的waitpid()函数

函数原型:

int pthread_join(pthread_t thread, void **retval);

函数返回值:

成功:0
失败:错误号

函数参数

thread:线程ID
retval:存储线程结束状态,整个指针和pthread_exit()的参数指向同一块内存地址

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<unistd.h>
#include<pthread.h>
int g_val = 9;
void *mythread(void *arg){
	printf("child thread, pid == [%d], id == [%ld]\n", getpid(), pthread_self());
	printf("[%p]\n", g_val);
	pthread_exit(&g_val);
}
int main(){
	pthread_t thread;
	int ret = pthread_create(&thread, NULL, mythread, NULL);
	if(ret != 0){
		printf("pthread_create error,[%s]\n",strerror(ret)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值