/**************************************************
相关函数:
#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);
}

最新文章

  1. c#接口
  2. zepto插件 countdown 倒计时插件 从jquery 改成 zepto
  3. oracle信息统计
  4. jpype调用jar
  5. git merge 和 rebase 区别
  6. ADODB.Connection 错误 ‘800a0e7a’ 未找到提供程序
  7. java jvm学习笔记十(策略和保护域)
  8. [wikioi]线段覆盖
  9. 如何安装Oracle Database 11g数据库
  10. jQueryMobile之弹出对话框
  11. sql基础复习
  12. 用RequireJS优化Wijmo Web页面
  13. 【转】Android常用工具类
  14. ajax数据请求5(php格式)
  15. 【学习】Linux Shell脚本实例之一
  16. Centos 编译 安装 criu
  17. python 通过 pip 更新所有已安装的包
  18. Database学习 - mysql 连接数据库 库操作
  19. wordpress更换主题未能连接到FTP服务器
  20. hdu 1735(贪心) 统计字数

热门文章

  1. 点击对应的a标签返回相应的第几个
  2. Android Studio模拟器的root权限
  3. HDU-2588-GCD (欧拉函数)
  4. 练习三十八:矩阵for循环应用
  5. 【tf.keras】tf.keras加载AlexNet预训练模型
  6. 从Flux到Redux详解单项数据流
  7. 检查python以及django是否安装配置成功
  8. 消除transition闪屏
  9. maven 配置Hibernate
  10. WebUploader实现采集图片的功能