线程取消
-
pthread_cancel #include<pthread.h>
int pthread_cancel(pthread_t thread);
函数pthread_cancel()可以向由thread指定的线程发送一个取消请求 发送取消请求后,函数pthread_cancel()当立即返回,不会等待目标线程的退出
取消的状态和类型
当执行取消操作,即pthread_cancel时,取消的结果取决于取消的状态和类型,可以通过下面的函数进行设置
#include<pthread.h>
int pthread_setcancelstate(int state, int *oldstate);
int pthread_setcanceltype(int type, int *oldtype);
函数pthread_setcancelstate会将调用线程的取消性状态设置为参数state所指定的状态,pthread_setcanceltype也是一样,state状态有如下两种
如果线程的取消状态为ENABLE,那么取消操作将会取决于取消的类型,有以下两种
参数oldstate/oldtype保存了上一次的状态或者类型
取消点
SUSv3规定,如果实现提供有下列函数,那么这些函数必须是取消点,即如果之前有取消请求,那么线程运行到此时必须终止 程序一旦收到取消请求,且启用了取消状态并将类型置为延迟,那么其会在下一次抵达取消点时终止,这种操作又被称为延迟取消
如果线程取消时未分离,那么为了防止其变成僵尸进程,必须手动对其进行连接,连接之后,返回给pthread_join()的第二个参数为
PTHREAD_CANCELED
可取消性的检测
清理函数
有时希望在线程结束之前做一些处理工作,如解锁或者清理空间等,此时就需要用到清理函数
每个线程都可以拥有一个清理函数栈,但线程遭到取消时,会沿着该栈自顶向下一次执行清理函数
#include<pthread.h>
void pthread_cleanup_push(void (routine)(void *), void *arg);
void pthread_join_pop(int execute);
顾名思义,pthread_clean_push()可将routine清理函数加入到清理函数栈中,pop()即将栈顶元素弹出
参数解释
arg是作为routine的参数传入
如果execute是非0值,那么执行pthread_join_pop()时就一定会触发栈顶的清理函数,如果为0,也有可能会执行栈顶函数
异步取消
若取消类型为PTHREAD_CANCEL_ASYNCHRONOUS,则为异步取消, 既可以在任何时点进行取消,这势必会造成混乱,尽量少用
|