日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

pthread_cancel 线程阻塞问题

發布時間:2023/12/20 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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 线程阻塞问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。