pthread_cancel 线程阻塞问题
背景
一個模塊頻繁啟動退出會出現退出阻塞的問題!
因為有特殊業務用同事非阻塞庫有問題,所以我暫時用線程阻塞加pthread_cancel強制退出;
肯定就是這個線程退出阻塞,加日志跟蹤之。。
懷疑在pthread_join,測試發現阻塞在pthread_cancel!!
分析
基本概念
pthread_cancel調用并不等待線程終止,它只提出請求。線程在取消請求(pthread_cancel)發出后會繼續運行,
直到到達某個取消點(CancellationPoint)。取消點是線程檢查是否被取消并按照請求進行動作的一個位置.
測試偽代碼
#include <unistd.h> #include <sys/types.h> #include<sys/socket.h> #include<netdb.h> #include<stdio.h> #include<stdlib.h> #include<string.h> #include<ctype.h> #include<errno.h> #include<malloc.h> #include<netinet/in.h> #include<arpa/inet.h> #include<sys/ioctl.h> #include<stdarg.h> #include<fcntl.h>static int socket_fd;static void* pthread_func(void* arg) {char buf[128] = {0};while(1){printf("read start \r\n");pthread_testcancel(); //阻塞時沒有這行read(socket_fd, buf, 128);pthread_testcancel();//阻塞時沒有這行printf("read end\r\n");}return NULL; }int main(int argc, char const *argv[]) {socket_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); pthread_t tid;pthread_create(&tid, NULL, pthread_func, NULL);sleep(2);printf("pthread_cancel tid[%d]\r\n", tid);int ret = pthread_cancel(tid);printf("ret[%d]\r\n", ret);pthread_join(tid, NULL);printf("pthread_join\r\n");close(socket_fd);socket_fd = -1;return 0; }非必現問題,必須實際環境測試, read要有接收
本地read無數據接收時無法復現問題!
原因
根據POSIX標準,pthread_join()、pthread_testcancel()、pthread_cond_wait()、pthread_cond_timedwait()、sem_wait()、sigwait()等函數以及
read()、write()等會引起阻塞的系統調用都是Cancelation-point,而其他pthread函數都不會引起Cancelation動作。
但是pthread_cancel的手冊頁聲稱,由于LinuxThread庫與C庫結合得不好,因而目前C庫函數都不是Cancelation-point;但CANCEL信號會使線程從阻塞的系統調用中退出,并置EINTR錯誤碼,因此可以在需要作為Cancelation-point的系統調用前后調用pthread_testcancel(),從而達到POSIX標準所要求的目標.
即如下代碼段:
pthread_testcancel();
retcode = read(fd, buffer, length);
pthread_testcancel();
注意:
程序設計方面的考慮,如果線程處于無限循環中,且循環體內沒有執行至取消點的必然路徑,則線程無法由外部其他線程的取消請求而終止。因此在這樣的循環體的必經路徑上應該加入pthread_testcancel()調用.
真相大白:
pthread_cancel的手冊頁聲稱:LinuxThread庫與C庫結合得不好,C庫函數都不是Cancelation-point, 需要作Cancelation-point的系統調用前后調用pthread_testcancel(),從而達到POSIX標準所要求的目標
參考
線程取消(pthread_cancel)
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處!
更多精彩內容,歡迎訪問一只海星的主頁
總結
以上是生活随笔為你收集整理的pthread_cancel 线程阻塞问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 插入排序算法(Java代码实现)
- 下一篇: PAT A1031