【那些年遇到过的面试题】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);
- 【那些年遇到过的面试题】pthread_cancel
- 【那些年遇到过的面试题】孩子 面试题
- 【那些年遇到过的面试题】关键字volatile
- 【那些年遇到过的面试题】 rpm包
- 【那些年遇到过的面试题】 explicit关键字
- 【那些年遇到过的面试题】switch case default
- 【那些年遇到过的面试题】并发服务器模型
- 【那些年遇到过的面试题】gdb调试多线程
- 【那些年遇到过的面试题】tcpdump
- 【那些年遇到过的面试题】 内存泄露
- 【那些年遇到过的面试题】malloc 原理
- 【那些年遇到过的面试题】linux 内核锁
- 【那些年遇到过的面试题】select poll epoll
- 【那些年遇到过的面试题】select 函数
- 【那些年遇到过的面试题】 epoll
- 【那些年遇到过的面试题】线程安全
- 【那些年遇到过的面试题】pthread_mutex
- 【那些年遇到过的面试题】pthread_cond
- 多段合并播放器方案(移动版)
- java反射获得泛型参数
- hibernate 的left join fetch可以取出lazy对象
- Plugin is too old, please update to a more recent version错误
- EventBus在项目中的应用
- 【那些年遇到过的面试题】pthread_cancel
- iOS 在Xcode7下免证书真机测试
- spring Model 传递参数的值
- hdoj 2504 又见GCD
- myeclipse更改某种后缀文件的打开方式
- setNeedsDisplay、setNeedsLayout
- JDBC 连接 hive2 遇到的java.lang.ClassNotFoundException: org.apache.hive.jdbc.HiveDriver
- 人物列传
- Qt之图形视图框架