/**************************************************
相关函数:
#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函数注意事项的更多相关文章

  1. js foreach函数 注意事项(break、continue)

    foreach API说明: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Arra ...

  2. pthread_testcancel和pthread_cancel函数的简单示例

    /*0.取消线程 int pthread_cancel(pthread_t thread); 设置取消点 void pthread_testcancel(void); 测试是否接收到取消请求,如果有, ...

  3. js自执行函数注意事项

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. c++虚函数注意事项

    >在基类方法声明中使用关键字virtual,可以使该方法在基类及所有的派生类中是虚的 >如果使用指向对象的引用或指针来调用虚方法,程序将使用对象类型定义的方法,而不使用为引用或指针类型定义 ...

  5. OpenCV中cvWaitKey()函数注意事项

    注意:这个函数是HighGUI中唯一能够获取和操作事件的函数,所以在一般的事件处理中,它需要周期地被调用,除非HighGUI被用在某些能够处理事件的环境中.比如在MFC环境下,这个函数不起作用.

  6. 内联汇编和JMP到内联函数注意事项

    对于jmp类型的hook, 如果自己的过程没有使用_declspec(naked),那么系统会自动给添加一些额外的代码,控制堆栈平衡,但是这些额外的代码会破坏被hook函数的堆栈. 对于call类型的 ...

  7. MySqL触发器以及常用转换函数注意事项

    1,触发器(http://www.cnblogs.com/zzwlovegfj/archive/2012/07/04/2576989.html)       1.MYSQL中触发器中不能对本表进行 i ...

  8. PLSQL 创建自定义函数注意事项

    2017-6-8周四,今天遇到的需求是,从数据库中查找出某张表的某些数据,并将这些数据做简单的加减运算再得到结果集,没有思路,后来问辉哥,给我的建议是给这些运算封装成一个SQL函数,select选择字 ...

  9. js- DOM事件之按钮绑定函数注意事项

    <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8&qu ...

随机推荐

  1. POJ1027 The Same Game

    题目来源:http://poj.org/problem?id=1027 题目大意: 题目说的就是现在蛮流行的手机小游戏popstar,求用贪心方法能得到多少分. 小球有三种颜色:R/G/B.横向.纵向 ...

  2. Python——连接数据库

    好用的教程(*^▽^*):https://www.cnblogs.com/fatcat132006/p/4081576.html

  3. Spark Mllib里如何采用保序回归做回归分析(图文详解)

    不多说,直接上干货! 相比于决策树,保序回归的应用范围没有决策树算法那么广泛. 特别在数据处理较为庞大的时候,采用保序回归做回归分析,可以极大地节省资源,从而提高计算效率. 保序回归的思想,是对数据进 ...

  4. SharePoint 2010开发方面的课堂中整理有关问题

    SharePoint 2010开发方面的课堂中整理有关问题 这是我这几天在做一个SharePoint开发的课程的时候,大家提出的一些问题,及我的解答,分享给更多的朋友参考一下 这个文档,也可以在这里下 ...

  5. docker exit status 255解决

    一 windows开发整docker就是痛苦,在公司win7电脑想拿起几年没再用的docker 结果直接报错 Error getting IP address: ssh command error: ...

  6. C#与重构(入门)

    C#与代码重构(入门) 重构(Refactoring)就是通过调整程序代码改善软件的质量.性能,使其程序的设计模式和架构更趋合理,提高软件的扩展性和维护性. 单从概念少来理解重构可能很抽象,那么通过下 ...

  7. HDU4352 XHXJ's LIS(LIS 状压)

    题意 题目链接 Sol 刚开始的思路是\(f[i][j]\)表示到第\(i\)位,LIS长度为\(j\)的方案. 然而发现根本不能转移,除非知道了之前的状态然后重新dp一遍.. 题解,,,挺暴力的把, ...

  8. fstab 解析

    某些时候当Linux系统下划分了新的分区后,需要将这些分区设置为开机自动挂载,否则,Linux是无法使用新建的分区的. /etc/fstab 文件负责配置Linux开机时自动挂载的分区. Window ...

  9. React 官网列子学习

    一个有状态的组件 除了接受输入数据(通过 this.props ),组件还可以保持内部状态数据(通过this.state ).当一个组件的状态数据的变化,展现的标记将被重新调用render() 更新. ...

  10. hihoCoder hiho一下 第二周 #1014 : Trie树(Trie树基本应用)

    思路: 完全看题目中的介绍就行了.还有里面的input写道:不保证是英文单词,也有可能是火星文单词哦.比赛结束后的提交是不用考虑26个字母之外的,都会AC,如果考虑128种可能的话,爆了内存.步骤就是 ...