RETURN VALUE
On success, these functions return 0; on error, they return a non-zero error number.
//成功返回0,失败返回错误码
ERRORS
The pthread_setcancelstate() can fail with the following error:
//pthread_setcancelstate()会有以下错误码
EINVAL Invalid value for state.
//取消状态是无效的
The pthread_setcanceltype() can fail with the following error:
//pthread_setcanceltype()会有以下错误码
EINVAL Invalid value for type.
//取消类型是无效的
CONFORMING TO
POSIX.1-2001.
NOTES
For details of what happens when a thread is canceled, see pthread_cancel(3).
//要知道取消到底会发生什么,请看手册pthread_cancel
Briefly disabling cancelability is useful if a thread performs some critical action that must not be interrupted by acancellation request. Beware
of disabling cancelability for long periods, or around operations that may block for long periods, since that will render the thread unresponsive
to cancellation requests.
Setting the cancelability type to PTHREAD_CANCEL_ASYNCHRONOUS is rarely useful. Since the thread could be canceled at any time, it
cannot safely reserve resources (e.g., allocating memory with malloc(3)), acquire mutexes, semaphores, or locks, and so on. Reserving
resources is unsafe because the application has no way of knowing what the state of these resources is when the thread is canceled; that is,
did cancellation occur before the resources were reserved, while they were reserved, or after they were released? Furthermore, some internal
data structures(e.g., the linked list of free blocks managed by the malloc(3) family of functions) may be left in an inconsistent state if cancellation
occurs in the middle of the function call. Consequently, clean-up handlers cease to be useful. Functions that can be safely asynchronously
canceled are called async-cancel-safe functions. POSIX.1-2001 only requires that pthread_cancel(3), pthread_setcancelstate(), and
pthread_setcanceltype() be async-cancel-safe. In general, other library functions can’t be safely called from an asynchronously cancelable thread.
One of the few circumstances in which asynchronous cancelability is useful is for cancellation of a thread that is in a pure compute-bound loop.
The Linux threading implementations permit the oldstate argument of pthread_setcancelstate() to be NULL, in which case the information about
the previous cancelability state is not returned to the caller. Many other implementations also permit a NULL oldstat argument, but POSIX.1-
2001 does not specify this point, so portable applications should always specify a non-NULL value in oldstate. A precisely analogous set of
statements applies for the oldtype argument of pthread_setcanceltype().
七、实例
1、程序框架
2、源代码
-
/*`DATE: 2015-3-26
-
*AUTHOR:WJ
-
*
-
*int pthread_cancle(pthread_t tid)
-
* 取消tid指定的线程,成功返回0。但是取消只是发送一个请求,
-
* 并不意味着等待线程终止,而且发送成功也不意味着tid一定会终止
-
*int pthread_setcancelstate(int state, int *oldstate)
-
* 设置本线程对Cancel信号的反应,state有两种值:PTHREAD_CANCEL_ENABLE(缺省)
-
* 和PTHREAD_CANCEL_DISABLE,分别表示收到信号后设为CANCLED状态和忽略CANCEL信
-
* 号继续运行;old_state如果不为NULL则存入原来的Cancel状态以便恢复。
-
*int pthread_setcanceltype(int type, int *oldtype)
-
* 设置本线程取消动作的执行时机,type由两种取值:PTHREAD_CANCEL_DEFFERED和
-
* PTHREAD_CANCEL_ASYNCHRONOUS,仅当Cancel状态为Enable时有效,分别表示收到信号
-
* 后继续运行至下一个取消点再退出和立即执行取消动作(退出);oldtype如果不为NULL
-
* 则存入运来的取消动作类型值。
-
*/
-
-
#include "apue.h"
-
-
void *thread_fun(void *arg)
-
{
-
int stateval;
-
int typeval;
-
stateval = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
-
if(stateval != 0)
-
{
-
printf("set cancel state failed\n");
-
}
-
printf("Im new thread\n");
-
sleep(4);
-
-
-
printf("about to cancel \n");
-
stateval = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
-
if(stateval != 0)
-
{
-
printf("set cancel state failed\n");
-
}
-
typeval = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
-
if(typeval != 0)
-
{
-
printf("set cancel type failed\n");
-
}
-
-
printf("first cancel point\n");
-
printf("second cancel point\n");
-
-
return (void *)20;
-
}
-
-
int main()
-
{
-
pthread_t tid ;
-
int err, cval, jval;
-
void *rval;
-
-
err = pthread_create(&tid, NULL, thread_fun, NULL);
-
if(err != 0)
-
{
-
printf("create thread failed\n");
-
return 0;
-
}
-
sleep(2);
-
-
cval = pthread_cancel(tid);
-
if(cval != 0)
-
{
-
printf("cancel thread failed\n");
-
}
-
jval = pthread_join(tid, &rval);
-
-
printf("new thread exit code is %d\n", (int *)rval);
-
-
return 0;
-
}
3、练习:证明线程可以自己取消自己
-
/*DATE: 2015-3-25
-
*AUTHOR: WJ
-
*DESCRIPTION: 一个新线程自己可以取消自己
-
* int pthread_cancel(pthread_t tid)
-
* 取消tid指定的线程,成功返回0。但是取消只是发送一个请求,并不意味着等待线程终止,而且发送成功也不意味着tid一定会终止
-
* int pthread_setcancelstate(int state, int *oldstate)
-
* 设置本线程对Cancel信号的反应,state有两种值:PTHREAD_CANCEL_ENABLE(缺省)和PTHREAD_CANCEL_DISABLE,
-
* int pthread_setcanceltype(int type, int *oldtype)
-
* 设置本线程取消动作的执行时机,type由两种取值:PTHREAD_CANCEL_DEFFERED和PTHREAD_CANCEL_ASYCHRONOUS,仅当Cancel状态为Enable时有效,分别表示收到
-
* 信号后继续运行至下一个取消点再退出和立即执行取消动作(退出);oldtype如果不为NULL则存入运来的取消动作类型值。
-
*/
-
#include "apue.h"
-
-
int err;
-
pthread_t tid;
-
-
void *thread_fun(void *arg)
-
{
-
printf("I'm new thread\n");
-
-
printf("I'm about to cancel myself\n");
-
//设置取消类型为延时取消
-
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
-
//设置取消状态为可以取消
-
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
-
//取消自己
-
err = pthread_cancel(pthread_self());
-
if(err == 0)
-
{
-
printf("cancel myself success\n");
-
}
-
printf("cancel myself failed\n");
-
-
pthread_exit((void *)0);
-
}
-
-
-
int main()
-
{
-
//创造新线程
-
err = pthread_create(&tid, NULL, thread_fun, NULL);
-
if(err != 0)
-
{
-
printf("create new thread1 failed\n");
-
return 0;
-
}
-
-
err = pthread_join(tid, NULL);
-
if(err != 0)
-
{
-
printf("main thread join new thread failed\n");
-
}
-
else
-
{
-
printf("main thread join new thread success\n");
-
}
-
return 0;
-
}