第一句子网 - 唯美句子、句子迷、好句子大全
第一句子网 > pthread_cancel 线程阻塞问题

pthread_cancel 线程阻塞问题

时间:2023-07-31 09:36:46

相关推荐

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)

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处!

更多精彩内容,欢迎访问一只海星的主页

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。