线程的退出
1、线程从执行函数中返回。
2、线程调用pthread_ exit 退出线程。
3、线程可以被同一.进程中的其它线程取消。
1
#include <pthread.h>
void pthread_exit(void *retval);
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
void *deal_fun(void *arg)
{
int i = 0;
for(i = 0; i < 5; i++)
{
printf("runing %d\n",i);
sleep(1);
if(i == 3)
{
pthread_exit(NULL);
}
}
}
int main(int argc, char const *argv[])
{
pthread_t tid;
pthread_create(&tid,NULL,deal_fun,NULL);
pthread_join(tid,NULL);
return 0;
}
运行结果:
runing 0
runing 1
runing 2
runing 3
2
int pthread_cancel(pthread_t thread);
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
void *deal_fun(void *arg)
{
int i = 0;
for(i = 0; i < 5; i++)
{
printf("runing %d\n",i);
sleep(1);
}
}
int main(int argc, char const *argv[])
{
pthread_t tid;
pthread_create(&tid,NULL,deal_fun,NULL);
sleep(3);
pthread_cancel(tid);
pthread_join(tid,NULL);
return 0;
}
运行结果
runing 0
runing 1
runing 2
线程取消状态的设置
线程的取消状态:能不能取消
是否接受该线程取消信号pthread_setcancelstate设置取消状态
接受信号: PTHREAD_ CANCEL_ ENABLE
不接受该信号: PTHREAD_CANCEL_DISABLE
线程的取消点:立即取消还是遇到取消点取消
是否立即取消该线程(默认遇到取消点才取消) pthread_ setcanceltype设置取消类型
立即取消: PTHREAD_ CANCEL_ ASYNCHRONOUS
取消点取消: PTHREAD CANCEL DEFERRED
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
void *deal_fun(void *arg)
{
//设置取消状态(能不能被取消)
//PTHREAD_CANCEL DISABLE不能取消
//pthread_setcancelstate(PTHREAD_ CANCEL_ DISABLE,NULL);
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
//设置取消点(立即取消遇到取消点)
//PTHREAD_CANCEL_ASYNCHRONOUS立即取消
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
int i = 0;
for (i = 0; i < 5; i++)
{
printf("runing %d\n", i);
sleep(1);
}
return NULL;
}
int main(int argc, char const *argv[])
{
pthread_t tid;
pthread_create(&tid, NULL, deal_fun, NULL);
sleep(3);
//给tid线程发送一个结束
pthread_cancel(tid);
pthread_join(tid, NULL);
return 0;
}
运行结果:
runing 0
runing 1
runing 2
3.注册线程清理函数
和进程的退出清理一样,线程也可以注册它退出时要调用的函数,这样的函数称为线程清理处理程序(thread cleanup handler)。
注意:
线程可以建立多个清理处理程序。
处理程序在栈中,故它们的执行顺序与它们注册时的顺序相反。
注册清理函数:
#include <pthread. h>
void pthread_cleanup_push(void (* routine) (void *),void *arg) ;
功能:将清除函数压栈。即注册清理函数。
参数:
routine:线程清理函数的指针。
arg:传给线程清理函数的参数。
弹出清理函数:
#include <pthread. h>
void pthread_cleanup_push(void (* routine) (void *),void *arg) ;
功能:将清除函数弹栈,即删除清理函数。
参数:
execute:线程清理函数执行标志位。
非0,弹出清理函数,执行清理函数。
0,弹出清理函数,不执行清理函数。
注意:
当线程执行以下动作时会调用清理函数:
1、调用pthread_ exit退出线程。
2、响应其它线程的取消请求。
3、用非零execute调用pthread_ cleanup_ pop。
无论哪种情况pthread_ cleanup_pop 都将删除上一次 pthread_ cleanup_ push 调用注册的清理处理函数。
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
void my_clean(void *arg) //arg = str
{
if (arg != NULL)
{
free(arg);
printf("str_free\n");
arg = NULL;
}
}
void *deal_fun(void *arg)
{
char *str = (char *)malloc(32);
strcpy(str, "hello world");
//注册清理函数
pthread_cleanup_push(my_clean, str);
sleep(2);
printf("str=%s\n",str);
pthread_exit(NULL);
//清理函数弹栈(pop和push必须成对出现即使不能执行)
pthread_cleanup_pop(1);
return NULL;
}
int main(int argc, char const *argv[])
{
pthread_t tid;
pthread_create(&tid, NULL, deal_fun, NULL);
pthread_join(tid, NULL);
return 0;
}
运行结果:
str=hello world
str_free