Linux:信号对多线程的影响
Linux: effect of signal on multiple threads
我不认为这是重复的。关于调用信号处理程序时其他线程会发生什么情况,我有一个非常具体的问题。
我有一个玩硬件的多线程程序。在获得 SIGTERM(来自父进程)时,我希望信号处理程序将硬件状态设置为给定状态,然后退出(1)。我明白,因为我没有玩信号掩码,主线程将处理信号。但它是一个多处理器系统 (raspberry pi),其他线程都 运行ning 相对于 main 具有高优先级。他们可能睡着了,但他们也可能在触摸硬件。
如果所有其他线程在信号到达时冻结,我很好 - 我直接从信号处理程序调用 exit(),其他线程将永远不会再 运行。但是,如果他们可以 运行 独立,他们可能会在我在处理程序中设置所需状态之后但在我退出之前对硬件大惊小怪。而且我找不到描述效果的文档。如果 "freeze everything but the signal handler" 不是默认值,是否有办法获得该行为?
我可以重新设计代码,将所有硬件处理放在一个线程中,让那个线程处理中断,但这很不方便——我现在的线程布局分工很好,每个线程都知道它是什么硬件可以触摸和何时。我宁愿不重新设计。
其他线程将继续 运行,而信号处理线程正在 运行ning。我不知道有什么冻结一切的机制。
但是,如果您有多个线程操作硬件,似乎您无论如何都应该有某种互斥机制。有效:
pthread_mutex_lock(&hardware_lock);
fiddle_with_hardware();
pthread_mutex_unlock(&hardware_lock);
然后您可以让您的信号处理线程获取锁,重置硬件状态并调用 exit
而无需 释放锁。 exit
调用将终止所有线程,并且由于持有锁,因此在终止之前没有其他线程能够干扰硬件。
如果您有多个线程都在操纵整个硬件状态的离散部分,您可以为每个状态部分创建一个单独的锁。然后让您的信号处理线程在设置最终硬件状态和调用 exit
之前获取 all 锁。由于在普通操作中,只有一个线程尝试访问状态的每个离散部分,因此额外锁定不会对性能产生可衡量的影响。
还有一件事。我认为 "since I didn't play with signal masks, the main thread will process the signal." 来自 pthreads(7)
:
是不准确的
According to POSIX.1, a process-directed signal (sent using kill(2), for example) should be handled by a single, arbitrarily selected thread within the process.
这意味着你应该使用pthread_sigmask
来确保SIGTERM
被引导到主线程。
我不认为这是重复的。关于调用信号处理程序时其他线程会发生什么情况,我有一个非常具体的问题。
我有一个玩硬件的多线程程序。在获得 SIGTERM(来自父进程)时,我希望信号处理程序将硬件状态设置为给定状态,然后退出(1)。我明白,因为我没有玩信号掩码,主线程将处理信号。但它是一个多处理器系统 (raspberry pi),其他线程都 运行ning 相对于 main 具有高优先级。他们可能睡着了,但他们也可能在触摸硬件。
如果所有其他线程在信号到达时冻结,我很好 - 我直接从信号处理程序调用 exit(),其他线程将永远不会再 运行。但是,如果他们可以 运行 独立,他们可能会在我在处理程序中设置所需状态之后但在我退出之前对硬件大惊小怪。而且我找不到描述效果的文档。如果 "freeze everything but the signal handler" 不是默认值,是否有办法获得该行为?
我可以重新设计代码,将所有硬件处理放在一个线程中,让那个线程处理中断,但这很不方便——我现在的线程布局分工很好,每个线程都知道它是什么硬件可以触摸和何时。我宁愿不重新设计。
其他线程将继续 运行,而信号处理线程正在 运行ning。我不知道有什么冻结一切的机制。
但是,如果您有多个线程操作硬件,似乎您无论如何都应该有某种互斥机制。有效:
pthread_mutex_lock(&hardware_lock);
fiddle_with_hardware();
pthread_mutex_unlock(&hardware_lock);
然后您可以让您的信号处理线程获取锁,重置硬件状态并调用 exit
而无需 释放锁。 exit
调用将终止所有线程,并且由于持有锁,因此在终止之前没有其他线程能够干扰硬件。
如果您有多个线程都在操纵整个硬件状态的离散部分,您可以为每个状态部分创建一个单独的锁。然后让您的信号处理线程在设置最终硬件状态和调用 exit
之前获取 all 锁。由于在普通操作中,只有一个线程尝试访问状态的每个离散部分,因此额外锁定不会对性能产生可衡量的影响。
还有一件事。我认为 "since I didn't play with signal masks, the main thread will process the signal." 来自 pthreads(7)
:
According to POSIX.1, a process-directed signal (sent using kill(2), for example) should be handled by a single, arbitrarily selected thread within the process.
这意味着你应该使用pthread_sigmask
来确保SIGTERM
被引导到主线程。