一尘不染

如何加入挂在阻塞IO上的线程?

linux

我有一个在后台运行的线程正在以阻塞方式从输入设备读取事件,现在当我退出应用程序时,我想正确清理线程,但是我不能只运行pthread_join(),因为该线程由于IO阻塞而永远不会退出。

我如何正确解决这种情况?我应该发送一个pthread_kill(theard,SIGIORM)还是一个pthread_kill(theard,SIGALRM)来中断该块?那两个信号是否正确?还是有另一种方法来解决这种情况,并让该子线程退出阻塞读取?

由于我的所有谷歌搜索人员都没有找到解决方案,因此目前有些不解。

这是在Linux上并使用pthreads。

编辑:我在SIGIO和SIGALRM上玩了一些,当我不安装信号处理程序时,它们破坏了阻塞的IO,但在控制台上给出了一条消息(“可能有I /
O”),但是当我安装信号处理程序时,为避免出现该消息,它们不再破坏阻塞的IO,因此线程不会终止。所以我有点回到第一步。


阅读 235

收藏
2020-06-07

共1个答案

一尘不染

随着事情的发展,旧问题很可能会得到新的答案,现在可以使用新技术 更好地 处理线程中的信号。

从Linux内核2.6.22开始,该系统提供了一个称为的新功能,该功能signalfd()可用于为给定的Unix信号集(完全杀死进程的信号)打开文件描述符。

// defined a set of signals
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGUSR1);
// ... you can add more than one ...

// prevent the default signal behavior (very important)
sigprocmask(SIG_BLOCK, &set, nullptr);

// open a file descriptor using that set of Unix signals
f_socket = signalfd(-1, &set, SFD_NONBLOCK | SFD_CLOEXEC);

现在,您可以使用poll()select()函数沿您正在监听的更常用的文件描述符(套接字,磁盘上的文件等)监听信号。

如果您想要一个可以一遍又一遍地检查信号和其他文件描述符的循环,则NONBLOCK很重要(即,在其他文件描述符上也很重要)。

我有一个这样的实现,可以与(1)计时器,(2)套接字,(3)管道,(4)Unix信号,(5)常规文件一起使用。实际上,实际上任何文件描述符加上计时器。

https://github.com/m2osw/snapcpp/blob/master/snapwebsites/libsnapwebsites/src/snapwebsites/snap_communicator.cpp

https://github.com/m2osw/snapcpp/blob/master/snapwebsites/libsnapwebsites/src/snap
/snap_communicator.h

您可能也对libevent等库感兴趣

2020-06-07