int pthread_detach(pthread_t thread); 成功:0;失败:错误号
作用:从状态上实现线程分离,注意不是指该线程独自占用地址空间。
线程分离状态:指定该状态,线程主动与主控线程断开关系。线程结束后(不会产生僵尸线程),其退出状态不由其他线程获取,而直接自己自动释放(自己清理掉PCB的残留资源)。网络、多线程服务器常用。
进程若有该机制,将不会产生僵尸进程。僵尸进程的产生主要由于进程死后,大部分资源被释放,一点残留资源仍存于系统中,导致内核认为该进程仍存在。(注意进程没有这一机制)
也可使用 pthread_create函数参2(线程属性)来设置线程分离。
一般情况下,线程终止后,其终止状态一直保留到其它线程调用pthread_join获取它的状态为止(或者进程终止被回收了)。但是线程也可以被置为detach状态,这样的线程一旦终止就立刻回收它占用的所有资源,而不保留终止状态。不能对一个已经处于detach状态的线程调用pthread_join,这样的调用将返回EINVAL错误(22号错误)。也就是说,如果已经对一个线程调用了pthread_detach就不能再调用pthread_join了。
//使用pthread_detach函数实现线程分离
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>void *tfn(void *arg)
{int n = 3;while (n--) {printf("thread count %d\n", n);sleep(1);}//return (void *)1;pthread_exit((void *)1);
}int main(void)
{pthread_t tid;void *tret;int err;#if 0pthread_attr_t attr; /*通过线程属性来设置游离态(分离态)*/pthread_attr_init(&attr);pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);pthread_create(&tid, &attr, tfn, NULL);#elsepthread_create(&tid, NULL, tfn, NULL);pthread_detach(tid); //让线程分离 ----自动退出,无系统残留资源#endifwhile (1) {err = pthread_join(tid, &tret);printf("-------------err= %d\n", err);if (err != 0)fprintf(stderr, "thread_join error: %s\n", strerror(err));elsefprintf(stderr, "thread exit code %d\n", (int)tret);sleep(1);}return 0;
}
[root@localhost 01_pthread_test]# ./pthrd_detach
-------------err= 22 //可见错误号是22
thread count 2
thread_join error: Invalid argument //错误号对应的详细解释
thread count 1
-------------err= 22
thread_join error: Invalid argument
-------------err= 22
thread count 0
thread_join error: Invalid argument
-------------err= 22
thread_join error: Invalid argument
-------------err= 22
thread_join error: Invalid argument
分析:
- 使用pthread_detach函数实现线程分离时,应当先创建线程(pthread_create),然后再用pthread_detach实现该线程的分离。因此,这种方式与修改线程属性来实现线程分离的方法相比,不会发生在线程创建函数还未来得及返回时子线程提前结束导致返回的线程号是错误的线程号的情况。因为采用这种方法,即使子线程提前结束(先于pthread_create返回),但是子线程还未处于分离状态,因此其PCB的残留信息依然存在,如线程号等一些系统资源,所以线程号等系统资源仍被占据,还未分配出去,所以创建函数返回的线程号依然是该线程的线程号;
- 对处于分离状态的线程进行回收,会出现错误,且错误编号为22;
- 还可采用修改线程属性的方法来实现线程分离。