我一直在尝试理解POSIX线程和POSIX信号交互的错综复杂之处。我特别感兴趣的是:
作为参考,我正在研究如何将TclX包转换为支持线程,或者如何拆分它,并至少使一些有用的部分支持线程。信号是其中一个特别有趣的部分。
发布于 2010-04-24 01:24:32
正如@zoli2k所指出的,显式地指定一个线程来处理您希望处理的所有信号(或一组线程,每个线程都具有特定的信号职责)是一种很好的技术。
告诉另一个线程(实际上可能很忙)的最好方法是什么,告诉它信号已经发生了,我可以安全地处理将一个信号已经发生的信息传递给其他线程吗,arrived?...
我不会说“最好的”,但这是我的建议:
阻塞main
中所有所需信号,以便所有线程都继承信号掩码。然后,将特殊的信号接收线程设计成一个信号驱动的事件循环,将新到达的信号作为发送给其他线程内的通信。
要做到这一点,最简单的方法是让线程使用sigwaitinfo
or sigtimedwait
在循环中接受信号。然后线程以某种方式转换信号,可能是广播一个pthread_cond_t
,用更多的I/O唤醒其他线程,将命令排入特定于应用程序的线程安全队列中,等等。
或者,特殊线程可以允许将信号传递给信号处理程序,仅在准备好处理信号时才取消对传递的屏蔽。(然而,通过处理程序的信号传递往往比通过sigwait
系列的信号接收更容易出错。)在这种情况下,接收器的信号处理程序执行一些简单的异步信号安全操作:设置sig_atomic_t
标志,调用sigaddset(&signals_i_have_seen_recently, latest_sig)
,将一个字节的write
()传递给非阻塞self-pipe,等等。然后,回到其屏蔽的主循环中,线程如上所述将信号的接收传递给其他线程。
(更新了 @caf,正确地指出sigwait
方法更优越。)
发布于 2010-04-05 01:26:27
根据POSIX标准,所有线程在系统上都应该使用相同的PID,并且可以使用pthread_sigmask()
为每个线程定义信号阻塞掩码。
由于每个PID只允许定义一个信号处理程序,因此我更喜欢在一个线程中处理所有信号,如果需要取消正在运行的线程,则发送pthread_cancel()
。它是反对pthread_kill()
的首选方式,因为它允许为线程定义清理函数。
在一些较旧的系统上,由于缺乏适当的内核支持,正在运行的线程的PID可能与父线程的PID不同。有关使用linuxThreads on Linux 2.4处理信号的信息,请参阅常见问题解答。
发布于 2010-04-08 04:48:32
到目前为止,我所处的位置:
我仍然需要对POSIX、pselect
、sigwait
、sigaltstack
以及其他一大堆POSIX(和非POSIX)进行比较。
https://stackoverflow.com/questions/2575106
复制相似问题