pthread_cancel函数注意事项
2017-08-04 20:49
183 查看
/************************************************** 相关函数: #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取消进程的其他线程
- 程序猿之---C语言细节22(函数返回指针注意事项<悬空指针>、查看进程可以分配的内存大小)
- OTL调用存储过程/函数及注意事项
- 多线程CreateThread函数的用法及注意事项
- 相关编译到Android细节总结 编译加入curl关联lib与头文件 && 解决pthread的cancel函数NDK不支持,找不到sockaddr_i
- 覆盖Thread的start()函数后的注意事项
- 多线程CreateThread函数的用法及注意事项
- 封装了envi函数的IDL发布程序的执行方法 以及注意事项
- strtok()函数的使用以及注意事项
- 包含有函数实现的.h文件注意事项
- Linux使用带时区转换的时间函数注意事项(负负得正)
- Eigen常用函数以及注意事项总结
- vector的所有函数和使用的注意事项
- C++派生类中定义基类的虚函数时需注意的事项
- c# Enum Flag 下使用 HasFlag() 函数的注意事项
- C++默认参数与函数重载 注意事项
- 多线程CreateThread函数的用法及注意事项
- STL标准库algorithm中remove()函数的一个小注意事项
- IN 函数 和 and 在where条件中联合使用的注意事项:
- read( )函数注意事项与不足