【那些年遇到过的面试题】pthread_cancel

来源:互联网 发布:c语言基础知识大全 编辑:程序博客网 时间:2024/04/30 12:36
#include <pthread.h>#include <stdio.h>#include <unistd.h>static int counter = 0;void *thread_routine(void *arg){printf("enter thread routine!\n");for(counter = 0; ; counter++){if((counter % 1000) == 0){printf("testcancel\n");pthread_testcancel();printf("111111testcancel\n");}}}int main(int argc, char *argv[]){pthread_t thread;void *result;int status;status = pthread_create(&thread, NULL, thread_routine, NULL);printf("calling pthread_cancel\n");status = pthread_cancel(thread);printf("calling pthread_join\n");status = pthread_join(thread, &result);if(result == PTHREAD_CANCELED){printf("Thread canceled at %d\n", counter);}sleep(1);return 0;}

#include <pthread.h>

int pthread_cancel(pthread_t thread);


一个线程可以通过此机制向另外一个线程发送结束请求,值得一提的是,接收此请求的线程可以通过本线程的两个属性来决定是否取消以及时同步(延时)取消还是异步(立即)取消。

函数成功返回,并不代表那线程就结束了。

下面看那两个属性设置:
#include <pthread.h>

 int pthread_setcancelstate(int state, int *oldstate);
int pthread_setcanceltype(int type, int *oldtype);


state的值及其意义如下:

PTHREAD_CANCEL_ENABLE:

表明此线程是可取消的,也就是说,在接收一个取消请求到来之后,它注定是要取消的,只不过它有两种取消方式,一种是同步取消,另外一种是异步取消,下面会详说的。

PTHREAD_CANCEL_DISABLE:

表明此线程是不可取消的,那么接收取消请求之后,它依然自我的执行。


type的值及其意义如下:

PTHREAD_CANCEL_DEFERRED:

表明在线程是可取消的情况下,它是同步(延时)取消的。所谓同步取消的意思就是说,在收到一个取消请求之后,它会继续执行下去,直到找到下一个取消点进行退出。

PTHREAD_CANCEL_ASYNCHRONOUS:

表明是异步取消方式,也就是说线程在收到取消请求之后,立即取消退出。


那么什么是取消点呢?:

取消点是在程序在运行的时候检测是否收到取消请求,是否允许允许操作执行的点。下面的POSIX线程函数就是取消点:
pthread_join()
pthread_cond_wait()
pthread_cond_timedwait()
pthread_testcancel()
sem_wait()
sigwait()

以及read()、write()等会引起阻塞的系统调用都是Cancelation-point,而其他pthread函数都不会引起Cancelation动作。


如果线程在加锁后解锁前被取消,锁将永远保持锁定状态,因此如果在关键区段内有取消点存在,或者设置了异步取消类型,则必须在退出回调函数中解锁。

这时我们可使用下面的两个函数:

#include <pthread.h>

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

void pthread_cleanup_pop(int execute);

在一个线程结束的时候,会自动执行一个clean-up函数柄,这个函数柄里有一个stack(栈),我们之前就通过pthread_cleanup_push往这个栈里压入了一个函数,我们压入很多个,然后退出的时候,clean-up函数柄会自动的从这些栈里拿出函数进行执行。

如果此函数没有异常退出,那这些栈的函数怎么办呢?我们可以通过phread_cleanup_pop弹出这些栈里的函数,注意,此时的参数要为0,如果非0的话,弹出的同时也会执行这些函数的。

那之前讲到的死锁问题我们可以这样解决:

pthread_cleanup_push(pthread_mutex_unlock, (void *) &mutex);

pthread_mutex_lock(&mutex);

/* do some work */

pthread_mutex_unlock(&mutex);

pthread_cleanup_pop(0);



0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 胖人走路磨大腿怎么办 脖子上长了个淋巴结怎么办 面部危险三角区长痘痘怎么办 儿童脖子上有淋巴结节怎么办 左侧颈根部淋巴结肿大怎么办 人的三角区肿了怎么办 刮三角区肿了怎么办 乳腺增生引起的腋窝淋巴结怎么办 右边脸比左边脸大怎么办 六个月宝宝脖子有点歪怎么办 大人的头偏了怎么办 宝宝脖子睡偏了怎么办 宝宝头歪向左边怎么办 一岁宝宝头歪怎么办 宝宝头往右边歪怎么办 八个月宝宝头歪怎么办 宝宝头往左边偏怎么办 11月婴儿歪脖子怎么办 婴儿头往左边偏怎么办 宝宝头网的高怎么办 宝宝头歪向一边怎么办 2岁宝宝头睡偏了怎么办 6岁儿童头有点歪怎么办 宝宝脖子有点偏左边歪怎么办 宝宝脖子偏了怎么办呢 斜颈导致的脸歪怎么办 斜颈手术后脸部还不对称怎么办 宝宝3个月斜颈怎么办 一岁八个月宝宝斜颈怎么办 四个月宝宝有点斜颈怎么办 一岁宝宝有点偏怎么办 6个月宝宝有点斜颈怎么办 四个月宝宝左侧胸锁乳突肌厚怎么办 脖子疼好几天了怎么办 有双下巴怎么办才能瘦掉 胃突然疼的厉害怎么办 手劳损痛的厉害怎么办 手臂扭到了很疼怎么办 寒湿导致肩膀痛怎么办 吃辣脖子肿了怎么办 脖子长了个肿瘤怎么办