线程终止:
1.start_routine回调函数执行return;
2.线程自身调用pthread_exit();
3.其他线程调用pthread_cancel(ID)将此进程终止;
任意线程调用exit()使整个进程退出。
线程回收:线程默认joinable状态,终止后需使用pthread_join回收资源;将子线程使用pthread_detach从主线程分离后处于unjoinable状态,系统等线程退出后自动回收资源。
常用的 函数调用如下:
pthread_exit()
:结束本线程
#include <pthread.h>
void pthread_exit(void *retval);
参数含义:
retval:线程返回值,其他线程调用pthread_join()接收。
pthread_cancel()
:向指定线程发出取消请求,使用pthread_join回收,
#include <pthread.h>
int pthread_cancel(pthread_t thread);
参数含义:
thread:要终止的线程ID;
返回值:执行成功返回0,成功不一定会让指定线程终止;执行失败返回错误号,
pthread_join()
:等待线程终止回收资源,获取返回值retval,
#include <pthread.h>
int pthread_join(pthread_t thread, void **retval);
参数含义:
thread:线程 ID。
retval:存放回收线程的返回值。
返回值:成功返回0,失败返回错误号。
pthread_detach()
:分离线程,线程终止后系统自动清理,分离后不能再使用join获取状态,
#include <pthread.h>
int pthread_detach(pthread_t thread);
参数含义:要分离的线程 ID。
返回值:成功返回0,失败返回错误号。
本章代码在thread/目录下,实验1:路径为:11_Linux系统开发进阶\Linux系统编程_章节使用资料。
使用pthread_cancel让线程退出,pthread_join回收,代码在cancel.c:
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
int i;
/*
* 线程调用的函数
*/
void * yellowFunc(void * arg)
{
char * str=(char *)arg;
while(1){
printf("%s 线程ID%ld, i=%d \n",str,pthread_self(),i);
i++;
sleep(1);
}
}
int main(int argc, const char *argv[])
{
pthread_t yellow;
//创建线程
pthread_create(&yellow,NULL,&yellowFunc,"Y");
sleep(5);//线程执行5秒后退出,退出后不再打印信息
pthread_cancel(yellow);
pthread_join(yellow,NULL);//回收
sleep(5);//线程退出5秒之后进程退出
return 0;
}
编译:gcc cancel.c -o cancel -lpthread
,运行结果:
使用pthread_exit让线程退出,pthread_join回收线程资源,代码在/thread/exit/目录下,
线程依次使用pthread_exit退出,然后pthread_join依次回收线程,main.c:
#include <unistd.h>
#include "thread.h"
int main(int argc, const char *argv[])
{
void * pret;
pthread_t yellowId,redId,greenId,blueId;
//创建线程
pthread_create(&yellowId,NULL,&yellowFunc,"Yellow");
pthread_create(&redId,NULL,&redFunc,"Red");
pthread_create(&greenId,NULL,&greenFunc,"Green");
pthread_create(&blueId,NULL,&blueFunc,"Blue");
//回收退出的线程并获取打印状态
pthread_join(yellowId,&pret);
printf("%s退出 \n",(char *)pret);
pthread_join(redId,&pret);
printf("%s退出 \n",(char *)pret);
pthread_join(greenId,&pret);
printf("%s退出 \n",(char *)pret);
pthread_join(blueId,&pret);
printf("%s退出 \n",(char *)pret);
return 0;
}
编译运行,可以看到线程按顺序依次退出并打印pthread_exit的返回值:
实验三:
使用pthread_detach()设置线程分离,pthread_exit()退出后,系统自动回收,最后调用pthread_join()发现报错,说明线程分离后线程自动释放。
实验代码在detach.c:路径为:11_Linux系统开发进阶\Linux系统编程_章节使用资料。
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
int i;
/*
* 线程调用的函数
*/
void * yellowFunc(void * arg)
{
char * str=(char *)arg;
while(1){
printf("%s 线程ID%ld, 执行%ds \n",str,pthread_self(),i);
i++;
sleep(1);
if(i==5){
pthread_exit(NULL);
}
}
}
int main(int argc, const char *argv[])
{
int ret;
pthread_t yellow;
//创建线程
pthread_create(&yellow,NULL,&yellowFunc,"Y");
//子线程从主线程分离
ret=pthread_detach(yellow);
if(ret != 0){
perror("pthread_detach");
}
//分离后使用join回收会返回错误号errno
ret = pthread_join(yellow,NULL);
if(ret != 0){
printf("join 失败 %s!\n",strerror(ret));
}
sleep(5);//线程退出5秒之后进程退出
return 0;
}
编译,gcc -o detach detach.c -lpthread
,运行结果如下,发现使用pthread_join()报错: