实现线程分离linux
int pthread_detach(pthread_t thread); 成功:0;失败:错误号ubuntu
线程分离状态:指定该状态,线程主动与主控线程断开关系。线程结束后,其退出状态不禁其余线程获取,而直接本身自动释放。网络、多线程服务器经常使用。服务器
进程如有该机制,将不会产生僵尸进程。僵尸进程的产生主要因为进程死后,大部分资源被释放,一点残留资源仍存于系统中,致使内核认为该进程仍存在。网络
也可以使用 pthread_create函数参2(线程属性)来设置线程分离。多线程
【练习】:使用pthread_detach函数实现线程分离 【pthrd_detach.c】函数
通常状况下,线程终止后,其终止状态一直保留到其它线程调用pthread_join获取它的状态为止。可是线程也能够被置为detach状态,这样的线程一旦终止就马上回收它占用的全部资源,而不保留终止状态。不能对一个已经处于detach状态的线程调用pthread_join,这样的调用将返回EINVAL错误。也就是说,若是已经对一个线程调用了pthread_detach就不能再调用pthread_join了。spa
/*** detach.c ***/ #include<unistd.h> #include<string.h> #include<pthread.h> #include<stdio.h> void *tfn(void *arg) { int n = 3; while(n--) { printf("thread count %d\n",n); sleep(1); } pthread_exit((void*)1); } int main() { pthread_t tid; void* tret; int err; pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED); pthread_create(&tid,&attr,tfn,NULL); while(1) { err = pthread_join(tid,&tret); printf("------------------- err = %d\n",err); if(0 != err) { fprintf(stderr,"thread_join error : %s\n",strerror(err)); } else { fprintf(stderr,"thread exit code %d\n",(int)tret); } sleep(1); } return 0; }
运行结果:线程
ubuntu1604@ubuntu:~/wangqinghe/linux/20190819$ ./detachcode
------------------- err = 22blog
thread_join error : Invalid argument
thread count 2
------------------- err = 22
thread_join error : Invalid argument
thread count 1
------------------- err = 22
thread_join error : Invalid argument
thread count 0
------------------- err = 22
thread_join error : Invalid argument
------------------- err = 22
thread_join error : Invalid argument
------------------- err = 22
thread_join error : Invalid argument
------------------- err = 22
thread_join error : Invalid argument
^C
杀死(取消)线程 其做用,对应进程中 kill() 函数。
int pthread_cancel(pthread_t thread); 成功:0;失败:错误号
【注意】:线程的取消并非实时的,而有必定的延时。须要等待线程到达某个取消点(检查点)。
相似于玩游戏存档,必须到达指定的场所(存档点,如:客栈、仓库、城里等)才能存储进度。杀死线程也不是马上就能完成,必需要到达取消点。
取消点:是线程检查是否被取消,并按请求进行动做的一个位置。一般是一些系统调用creat,open,pause,close,read,write..... 执行命令man 7 pthreads能够查看具有这些取消点的系统调用列表。也可参阅 APUE.12.7 取消选项小节。
可粗略认为一个系统调用(进入内核)即为一个取消点。如线程中没有取消点,能够经过调用pthreestcancel函数自行设置一个取消点。
被取消的线程, 退出值定义在Linux的pthread库中。常数PTHREAD_CANCELED的值是-1。可在头文件pthread.h中找到它的定义:#define PTHREAD_CANCELED ((void *) -1)。所以当咱们对一个已经被取消的线程使用pthread_join回收时,获得的返回值为-1。
【练习】:终止线程的三种方法。注意“取消点”的概念。 【pthrd_endof3.c】
总结:终止某个线程而不终止整个进程,有三种方法:
/*** pthread_endof3.c ***/ #include <stdio.h> #include <unistd.h> #include <pthread.h> #include <stdlib.h> void *tfn1(void *arg) { printf("thread 1 returning\n"); return (void *)111; } void *tfn2(void *arg) { printf("thread 2 exiting\n"); pthread_exit((void *)222); } void *tfn3(void *arg) { while (1) { //printf("thread 3: I'm going to die in 3 seconds ...\n"); //sleep(1); pthread_testcancel(); //本身添加取消点*/ } return (void *)666; } int main(void) { pthread_t tid; void *tret = NULL; pthread_create(&tid, NULL, tfn1, NULL); pthread_join(tid, &tret); printf("thread 1 exit code = %d\n\n", (int)tret); pthread_create(&tid, NULL, tfn2, NULL); pthread_join(tid, &tret); printf("thread 2 exit code = %d\n\n", (int)tret); pthread_create(&tid, NULL, tfn3, NULL); sleep(3); pthread_cancel(tid); pthread_join(tid, &tret); printf("thread 3 exit code = %d\n", (int)tret); return 0; }
ubuntu1604@ubuntu:~/wangqinghe/linux/20190819$ ./pthread_endof3
thread 1 returning
thread 1 exit code = 111
thread 2 exiting
thread 2 exit code = 222
thread 3 exit code = -1