接上一篇,线程的取消例程函数实现,取消例程函数 pthread_cleanup_push()在线程中删除线程取消例程函数pthread_cleanup_pop()
三、线程的取消例程函数。
1、什么是线程取消例程函数?
当线程收到取消请求时,先不要马上响应取消,而是先执行一个例程函数先,执行完这个函数再响应取消。
2、为什么要使用线程取消例程函数?
在一个进程中,有可能有多个线程使用同一个资源,如果某一个线程因为被取消了而导致线程提前退出,那么它就会带着资源一起退出,那么其他一起使用该资源的线程就无法使用该资源。
解决方案:先告诉所有的线程,将来收到取消请求时,先释放资源,再响应取消,那么这样做,就可以避免这些线程带着资源而退出。
3、如何实现?
1)在线程例程中说明线程取消例程函数是哪个? --> pthread_cleanup_push() --> man 3 pthread_cleanup_push
#include
void pthread_cleanup_push(void (*routine)(void *),void *arg);
参数:
routine:线程取消例程函数 必须长这个样子: void func(void *arg)
arg:传递给线程取消例程函数的参数
返回值:无
回忆学过的例程函数:
信号处理函数: void func(int sig)
线程例程函数: void *func(void *arg)
线程取消例程函数:void func(void *arg)
2)在线程中删除线程取消例程函数? --> pthread_cleanup_pop() --> man 3 pthread_cleanup_pop
#include
void pthread_cleanup_pop(int execute);
参数:
execute: 0 --> 直接删除
非0 --> 先执行一遍,再删除
----------------------程序框架---------------------
//线程取消例程函数
void my_fun(void *arg)
{
}
//子线程例程函数
void *func(void *arg)
{
//1. 说明线程取消例程函数是哪个?
pthread_cleanup_push(my_fun,NULL);
.....
..... <-- 收到取消请求,先执行一遍my_fun,然后线程就退出。
.....
.....
//2. 删除线程取消例程函数
//pthread_cleanup_pop(0); 直接删除my_fun函数,不会执行。
pthread_cleanup_pop(1); 先执行一遍my_fun,然后再删除。
}
代码执行效果:
将来收到取消请求,先不会马上响应,而是先执行完my_fun这个函数之后,再响应取消。
练习4:
void my_fun(void *arg)
{
printf("helloworld!\n");
}
void *func(void *arg)
{
pthread_cleanup_push(my_fun,NULL);
.....
.....
..... <---- 收到取消请求
.....
pthread_cleanup_pop(0);
}
答案:打印一个helloworld,然后线程退出。
练习5:
void my_fun(void *arg)
{
printf("helloworld!\n");
}
void *func(void *arg)
{
pthread_cleanup_push(my_fun,NULL);
.....
.....
..... <---- 收到取消请求 (收到取消请求时,先执行一遍打印一次helloworld,然后线程退出(顺便删除取消例程函数))
.....
pthread_cleanup_pop(1);
}
答案:打印一个helloworld,然后线程退出。
练习6:
void my_fun(void *arg)
{
printf("helloworld!\n");
}
void *func(void *arg)
{
pthread_cleanup_push(my_fun,NULL);
.....
.....
..... <---- 一直都没有收到取消请求
.....
pthread_cleanup_pop(0);
}
答案:没有任何打印,线程正常退出。
练习7:
void my_fun(void *arg)
{
printf("helloworld!\n");
}
void *func(void *arg)
{
pthread_cleanup_push(my_fun,NULL);
.....
.....
..... <---- 一直都没有收到取消请求
.....
pthread_cleanup_pop(1);
}
答案:打印一个helloworld,然后线程退出。