1.假设有两个线程
A线程负责输出奇数。B线程负责输出偶数。
2.当A线程进入锁定状态是,主线程突然异常将A线程停止,这时将导致B线程也无法继续执行,处于死锁状态。如下代码:
#include <stdio.h> #include <stdlib.h> #include <pthread.h> pthread_mutex_t m; void *runodd(void *d) { int i=0; for(i=1;;i+=2) { pthread_mutex_lock(&m); printf("奇数:%d ",i); usleep(100); pthread_mutex_unlock(&m); } } void *runeven(void *d) { int i=0; for(i=0;;i+=2) { pthread_mutex_lock(&m); printf("偶数:%d ",i); usleep(100); pthread_mutex_unlock(&m); } } main() { pthread_t todd,teven; pthread_mutex_init(&m,0); pthread_create(&todd,0,runodd,0); pthread_create(&teven,0,runeven,0); sleep(5); printf("外部强制停止todd线程 "); pthread_cancel(todd); pthread_join(todd,(void**)0); pthread_join(teven,(void**)0); pthread_mutex_destroy(&m); }
解决方法:
运用2个函数(其实是2个宏)
pthread_cleanup_push
pthread_cleanup_pop 这个对函数作用类似于atexit函数
注意:这不是函数而是宏。必须成对使用。
void pthread_cleanup_push(
void (*routine)(void *),//回调函数
void *arg //回调函数的参数
);
触发调用routine的条件:
- 执行了exit()。
- 执行了pthread_cancel()
- pthread_cleanup_pop(1);//参数必须是1
#include <stdio.h> #include <stdlib.h> #include <pthread.h> pthread_mutex_t m; void handle(void *d) { printf("退出后的调用! "); pthread_mutex_unlock(&m); } void *runodd(void *d) { int i=0; for(i=1;;i+=2) { pthread_cleanup_push(handle,0); pthread_mutex_lock(&m); printf("奇数:%d ",i); usleep(100); pthread_mutex_unlock(&m); pthread_cleanup_pop(0); } } void *runeven(void *d) { int i=0; for(i=0;;i+=2) { pthread_mutex_lock(&m); printf("偶数:%d ",i); usleep(100); pthread_mutex_unlock(&m); } }