线程取消点


线程取消

取消操作允许线程请求终止其所在进程总的任何其他线程。不需要线程执行进一步操作时,可以选择取消操作。

取消点:

如果线程模式设置的是异步模式的话,那只有到取消点才会取消线程。下面会讲到两种取消方式。

那取消点有哪些呢?

1:通过pthread_testcancel 调用已编程方式建立线程取消点

2:线程等待pthread_cond_wait或pthread_cond_timewait中的特定条件

3:被sigwait(2)阻塞的函数

4:一些标准的库调用。通常这些调用包括线程可基于阻塞的函数

default情况下,会启用取消功能。

POSIX标准中,pthread_join(),pthread_testcancel().pthread_cond_wait(),pthread_cond_timewait(),sem_wait(),sigwait()等函数以及read,write等会引起阻塞的系统调用。


取消线程函数

int pthread_cancel(pthread_t thread);

成功之后返回0,失败返回错误号,错误号说明如下:

ESRCH:没有找到线程ID相对应的线程。

int phread_setcancelstate(int state,int *oldstate);设置本线程对信号的反应:

状态:

PTHREAD_CANCEL_ENABLE 默认,收到cancel信号马上设置退出状态

PTHREAD_CANCEL_DISABLE 很明显不处理cancel

返回值:

成功之后返回0.失败返回错误号,错误号说明如下:

EINVAL:状态不是PTHREAD_CANCEL_ENABLE或者PTHREAD_CANCEL_DISABLE

那取消方式呢?取消方式有两种,当然只有在PTHREAD_CANCEL_ENABLE状态下有效

int pthread_setcanceltype(int type, int *oldtype); 

PTHREAD_CANCEL_ASYNCHRONOUS 立即执行取消信号

 PTHREAD_CANCEL_DEFERRED 运行到下一个取消点

有什么区别呢?

在延迟模式(PTHREAD_CANCEL_DEFERRED)下,只能在取消点取消线程,在异步模式下,可以在任意一点取消线程,这建立还是用延迟模式

注意:当取消线程后,线程里面的锁可能还没有unlock,那么就会出现死锁的情况,如何避免呢?

这里介绍下清理处理程序,它可以将状态恢复到与起点一致的状态,其中包括清理已分配的资源和恢复不变量

使用pthread_cleanup_push和pthread_cleanup_pop,

push函数是将处理程序推送到清理栈,执行顺序自然是FIFO

void pthread_cleanup_push(void(*routine)(void *) , void (args);

有了这个清理函数,我们只需要把线程要清理的函数push上去,把unlock放在里面,就不会死锁了,当然之前还要lock一下mutex。

void cleanup(void *arg)
{
 pthread_mutex_unlock(&mutex);
}

这里举个取消点的例子:

 #include <pthread.h>
 #include <stdio.h>
 #include <unistd.h>

 void* thr(void* arg)
{

         pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
         pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,NULL);

         while(1)
         {
             pthread_testcancel();

         }
         printf("thread is not running\n");
         sleep(2);
}
int main()
{
         pthread_t tid;
         int err;
         err = pthread_create(&tid,NULL,thr,NULL);
         pthread_cancel(tid);
         pthread_join(tid,NULL);
         sleep(1);
         printf("Main thread exited\n");
         return 0;

}

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值