什么是分离和非分离
用来决定一个线程以什么方式来终止自己。
非分离:线程结束之后,需要主线程调用pthread_join()回收资源
分离:一个线程结束时就立即释放它的所占有的所有系统资源
pthread_join 的概念:
pthread_join函数主要用来获得另一个线程的终止状态并且释放该线程所占的资源。
当调用pthread_join()时,当前线程会处于阻塞状态,直到被调用的线程结束后,当前线程才会重新开始执行。
当pthread_join()函数返回后,被调用线程才算真正意义上的结束,它的内存空间也会被释放(如果被调用线程是非分离的)。
说明:
1)被释放的内存空间仅仅是系统空间,你必须手动清除程序分配的空间,比如malloc()分配的空间。
2)一个线程只能被一个线程所连接。
3)被连接的线程必须是非分离的,否则连接会出错。
函数结构
头文件#include<pthread.h>
函数原型int pthread_join(pthread_t thread,void* retval);
返回值成功:0,失败:返回错误码
参数列表
pthread_t thread:等待回收的线程ID
void* retval:回收线程的返回值
代码实例
#include<pthread.h>
#include<stdio.h>
void *first_func(void* arg)
{
int i;
int ret = 1;
printf("firstpthread,pid=%d,first_tid=%lu\n",
(int)getpid(),unsigned long)pthread_self());
for(i=0;i<3;)
{
printf("funccnt=%d\n",++i);
sleep(1);
}
/*调试1:直接return*/
//return (void*)ret;
/*调试2:不带参数的pthread_exit*/
//pthread_exit(NULL);
}
int main()
{
int err,i;
void *retval;
pthread_t tid;
err = pthread_create(&tid,NULL,(void*)first_func,NULL);
if(err != 0)
{
printf("failtocreatapthread\n");
return -1;
}
err = pthread_join(tid,NULL);
if(err!=0)
{
printf("failtowaitpthread\n");
return-1;
}
printf("exit....\n");
return 0;
}
phread_detach的概念:
pthread_detach()函数可以将一个线程设置为detached状态,从而让操作系统在该线程结束时来回收它所占的资源。
函数结构:
头文件#include<pthread.h>
函数原型intpthread_detach(pthread_t tid);
参数列表
tid:线程标识符
返回值
pthread_detach()在调用成功完成之后返回零。其他任何返回值都表示出现了错误。
EINVAL:tid是分离线程
ESRCH:tid不是当前进程中有效的为分离线程
代码实例:
#include<pthread.h>
#include<stdio.h>
#include<string.h>
void *first_func(void *arg)
{
inti;
/*
for(i=0;i<5;i++)
{
printf("firstthread...\n");
sleep(1);
}
printf("childthreaddone\n");
*/
pthread_detach(pthread_self());
}
int main()
{
int err,i;
void *retval1,*retval2;
pthread_t tid1,tid2;
err=pthread_create(&tid1,NULL,(void*)first_func,NULL);
if(err!=0)
{
printf("failtocreatapthread\n");
return-1;
}
sleep(1);
pthread_detach(tid1);
/*主线程有其他重要的事*/
for(i=0;i<10;i++)
{
printf("mainthread-----\n");
sleep(1);
}
printf("exit....\n");
return0;
}
区别
在主线程正常创建一个线程,这个线程在主线程结束之前终止了,运行完了。那这个线程没有join。该终止线程占用的资源,系统将无法回收,也叫作僵尸线程。因此,我们去join某个线程,意思是告诉操作系统,这个线程终止后的资源可以回收了。
detach的作用是分离某个线程,因为线程被创建时的状态是非分离的,被分离的线程终止后,系统能自动回收该线程占用的资源。
1. pthread_join()是阻塞式的,假设主线程A创建了线程B,线程A join了线程B,也叫连接。那么线程A会阻塞在pthread_join()这个函数调用,直到线程B终止。
2. pthread_detach()是非阻塞式的,线程A分离(detach)了线程B,那么线程A不会阻塞在pthread_detach(),pthread_detach()会直接返回,线程B终止后会被操作系统自动回收资源。
3 如果从输出来看,假如线程A和被创建的线程B同时循环输出"A"和“B”,那么在执行到join时,代码的输出会全部变成“B”,“B”,“B”,...直到B终止。假如执行的是deatch,那么在并发上,"A","B"会随机输出。