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\n",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\n",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線程\n"); 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("退出后的調用!\n"); 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\n",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\n",i); usleep(100); pthread_mutex_unlock(&m); } }