线程分离
在线程终止后,其它线程调用pthread_join()函数获取该线程的终止状态之前,该线程会一直保持终止状态,这种状态类似进程中的僵尸态。虽然处于僵尸态的进程中大部分资源都已经被释放,但因为仍有少许资源残留,进程会保持僵尸态一直存在于系统中,也因此内核会认为进程仍然存在,僵尸进程无法被回收。线程机制中提供了pthread_detach()函数,对进程的这一不足做了完善。
pthread_detach()函数会将线程从主控线程中分离,如此,当线程结束后,它的退出状态不由其它线程获取,而是由该线程自身自动释放。pthread_detach()函数位于函数库pthread.h中,其声明如下:
int pthread_detach(pthread_t thread);
pthread_detach()函数的参数thread为待分离线程的id,若该函数调用成功则返回0,否则返回errno。需要注意的是,pthread_join()不能终止已处于death状态的线程,若对处于分离态的线程调用pthread_join()函数,函数将会调用失败并返回EINVAL。
下面通过一个案例来展示pthread_detach()函数的用法。
案例7:使用pthread_detach()函数分离子线程,使子线程自动回收。
1 #include <stdio.h>
2 #include <unistd.h>
3 #include <pthread.h>
4 #include <stdlib.h>
5 #include <string.h>
6 void *tfn(void *arg)
7 {
8 int n = 5;
9 while (n--) {
10 printf("pthread tfn n = %d\n", n);
11 sleep(1);
12 }
13 return (void *)7;
14 }
15 int main(void)
16 {
17 pthread_t tid;
18 void *ret;
19 pthread_create(&tid, NULL, tfn, NULL);
20 pthread_detach(tid); //分离子线程
21 int retvar = pthread_join(tid, (void **)&ret);
22 if (retvar != 0) {
23 fprintf(stderr, "pthread_join error %s\n", strerror(retvar));
24 }
25 else
26 {
27 printf("pthread exit with %ld\n", (long int)ret);
28 }
29 return 0;
30 }
编译案例7,执行程序,执行结果如下所示。
pthread exit with 140736101144272
观察执行结果,其中获取的返回值与第13行代码中设置的返回值显然不同,说明pthread_join()函数调用失败,由此反证pthread_detach()函数调用成功,此时子线程已处于分离状态。若子线程有机会执行,在其执行完毕后,会自动释放自身占用的全部资源。