pthread_cancel函数注意事项
/**************************************************
相关函数:
     #include <pthread.h>
     int pthread_cancel(pthread_t thread)
                     成功返回0,失败返回错误码
**************************************************/
此函数是POSIX提供的用于取消同一进程中的其它线程,此函
数只发送取消请求,并不等待要取消的进程退出!线程可以
选择忽略或是选择其它动作!
需要注意的是:
当我们调用它取消一个已经获得互斥锁/匿名信号量/写锁....但
还未释放其所获得锁的线程时,如果此线程被取消,此后所有想
要获得此时执行任务的线程都将处于睡眠状态,直到此锁被释放.
为避免此问题的产生,我们可以调用一组函数:
/**************************************************
    #include <pthread.h>
    void pthread_cleanup_push(void (*routine)(void *), void *arg)
    void pthread_cleanup_pop(int execute)
        参数解释:routine为函数指针,arg为传递给routine的参数
        execute为零时,从栈中删除注册的函数,删除后将再也
        不被执行。
**************************************************/
这两个函数被称为线程清理处理程序,类似于atexit函数,我们
可以注册多个清理函数,当执行以下动作时我们所注册的函数将会
回调(执行顺序与注册顺序相反):
    1.线程从pthread_exit(void *)函数退出时。
    2.线程响应取消请求时。
    3.执行pthread_cleanup_pop函数,execute参数为非零时。
这两个线程清理处理程序必须成对出现,必须处于同一作用域中,
否则会编译出错。实例:
    如何使用这些函数处理以上问题!
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <signal.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <pthread.h>
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
void *count(void *arg)
{
    int i=1;
    while(1)
    {
        sleep(1);
        printf("sec: %d\n", i++);
    }
}
void handler(void *arg)
{
    printf("[%u] is cancelled.\n", (unsigned)pthread_self());
    pthread_mutex_t *pm = (pthread_mutex_t *)arg;
    pthread_mutex_unlock(pm);
}
void *routine(void *arg)
{
    #ifdef CLEANUP
    pthread_cleanup_push(handler, (void *)&m);
    #endif
    pthread_mutex_lock(&m);
    printf("[%u] lock the mutex!\n", (unsigned)pthread_self());
    /*
    ** During sleep(), if the calling thread received a cancel-
    ** request and HASN'T established any cleanup handlers to
    ** unlock the mutex, it will leave the mutex a DEAD-LOCK
    ** state.
    */
    sleep(2);
    printf("[%u]: job finished!\n", (unsigned)pthread_self());
    pthread_mutex_unlock(&m);
    printf("[%u] unlock the mutex!\n", (unsigned)pthread_self());
    /*
    ** NOTE:
    **
    ** pthread_cleanup_push() and pthread_cleanup_pop() may be
    ** implemented as macro that expand to text containing '{'
    ** and '}', respectively. For this reason, the caller must
    ** user them pairly and ensure that they are paired within
    ** a same function and at the same lexical nesting level.
    */
    #ifdef CLEANUP
    pthread_cleanup_pop(0);
    #endif
    pthread_exit(NULL);
}
int main(int argc, char **argv)
{
    pthread_t t, t1, t2;
    pthread_create(&t, NULL, count, NULL);
    pthread_create(&t1, NULL, routine, NULL);
    pthread_create(&t2, NULL, routine, NULL);
    printf("[%u] ==> t1\n", (unsigned)t1);
    printf("[%u] ==> t2\n", (unsigned)t2);
    printf("[%u] ==> main\n", (unsigned)pthread_self());
    sleep(1);
    pthread_cancel(t1);
    pthread_cancel(t2);
    sleep(2);
    pthread_mutex_lock(&m);
    printf("[%u] locked the mutex!\n",
        (unsigned)pthread_self());
    pthread_mutex_unlock(&m);
    exit(0);
}
pthread_cancel函数注意事项的更多相关文章
- js foreach函数 注意事项(break、continue)
		foreach API说明: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Arra ... 
- pthread_testcancel和pthread_cancel函数的简单示例
		/*0.取消线程 int pthread_cancel(pthread_t thread); 设置取消点 void pthread_testcancel(void); 测试是否接收到取消请求,如果有, ... 
- js自执行函数注意事项
		<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ... 
- c++虚函数注意事项
		>在基类方法声明中使用关键字virtual,可以使该方法在基类及所有的派生类中是虚的 >如果使用指向对象的引用或指针来调用虚方法,程序将使用对象类型定义的方法,而不使用为引用或指针类型定义 ... 
- OpenCV中cvWaitKey()函数注意事项
		注意:这个函数是HighGUI中唯一能够获取和操作事件的函数,所以在一般的事件处理中,它需要周期地被调用,除非HighGUI被用在某些能够处理事件的环境中.比如在MFC环境下,这个函数不起作用. 
- 内联汇编和JMP到内联函数注意事项
		对于jmp类型的hook, 如果自己的过程没有使用_declspec(naked),那么系统会自动给添加一些额外的代码,控制堆栈平衡,但是这些额外的代码会破坏被hook函数的堆栈. 对于call类型的 ... 
- MySqL触发器以及常用转换函数注意事项
		1,触发器(http://www.cnblogs.com/zzwlovegfj/archive/2012/07/04/2576989.html) 1.MYSQL中触发器中不能对本表进行 i ... 
- PLSQL 创建自定义函数注意事项
		2017-6-8周四,今天遇到的需求是,从数据库中查找出某张表的某些数据,并将这些数据做简单的加减运算再得到结果集,没有思路,后来问辉哥,给我的建议是给这些运算封装成一个SQL函数,select选择字 ... 
- js- DOM事件之按钮绑定函数注意事项
		<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8&qu ... 
随机推荐
- codeforces round 472(DIV2)D Riverside Curio题解(思维题)
			题目传送门:http://codeforces.com/contest/957/problem/D 题意大致是这样的:有一个水池,每天都有一个水位(一个整数).每天都会在这一天的水位上划线(如果这个水 ... 
- Codeforces 1161C(博弈)
			自己的一点想法 举几个例子后发现是谁先手痒痒把某一堆掏空了那他就GG了,因此要尽量让对方不得不掏空某堆. 用最简单的举例后发现:1 1 1 1 1 1,扔给谁谁完蛋:1 1 1 1 1 2,一样的,肯 ... 
- echart与Accelerometer综合
			首先是x,y,z轴的加速度统计,利用四个数组记录,并长度为偶数时生成图表 var x=[]; var y=[]; var z=[]; var t=[]; document.addEventListen ... 
- 弹层组件文档 - layui.layer
			http://www.layui.com/doc/modules/layer.html 
- Chapter12
			package scalaimport java.awt.event.{ActionEvent, ActionListener}import javax.swing.JButton import sc ... 
- Tkinter的l组件常用属性
			Label常用属性 序号 属性 说明 1 anchor 指示文字会被放在控件的什么位置, 可选项有 N, NE, E, SE, S, SW, W, NW, CENTER. 默认为 CENTER. ... 
- UiAutomator环境配置
			前提:下载jdk以及adt 一.配置java开发环境 1.新建系统变量 -——变量名:JAVA_HOME 变量值:C:\Program Files\Java\jdk1.7.0_80 2.编辑 ... 
- OpenStack Weekly Rank 2015.07.20
			Module Reviews Drafted Blueprints Completed Blueprints Filed Bugs Resolved Bugs Cinder 8 1 3 9 10 Sw ... 
- sqoop导出hive数据到mysql错误: Caused by: java.lang.RuntimeException: Can't parse input data
			Sqoop Export数据到本地数据库时出现错误,命令如下: sqoop export \ --connect 'jdbc:mysql://202.193.60.117/dataweb?useUni ... 
- Editplus配置java编译环境
			EditPlus配置java编译环境 第一步:检测自己是否已经有jdk 1.win+r,输入cmd,打开控制台 2.控制台下输入javac出现类似的画面,代表jdk已经成功安装 第二步:打开Editp ... 
