我不认为这是重复的。我有一个非常具体的问题,关于调用信号处理程序时其他线程会发生什么。
我有一个与硬件一起玩的多线程程序。在获取SIGTERM(来自父进程)时,我希望信号处理程序将硬件状态设置为给定状态,然后退出(1)。据我所知,由于我没有使用信号掩码,主线程将处理信号。但它是一个多处理器系统(raspberry pi),其他线程都相对于main运行在高优先级。他们可能已经睡着了,但他们也可能会碰到硬件。
如果所有其他线程在信号到达时冻结,我很好 - 我直接从信号处理程序调用exit(),其他线程将永远不再运行。但是如果它们可以独立运行,那么在我在处理程序中设置所需状态之后,在我退出之前,它们可能会对硬件大惊小怪。我找不到描述效果的文档。如果“冻结除信号处理程序之外的所有内容”不是默认值,是否有办法获得该行为?
我可以重新设计代码以将所有硬件处理放在一个线程中,并使该线程处理中断,但这很不方便 - 我现在的线程布局做了很好的分工,每个线程知道它可以触摸哪些硬件什么时候。我宁愿不重新设计。
答案 0 :(得分:2)
在信号处理线程运行时,其他线程将继续运行。我不知道任何冻结一切机制。
但是,如果您有多个线程操作硬件,那么您似乎应该拥有某种互斥机制。实际上:
pthread_mutex_lock(&hardware_lock);
fiddle_with_hardware();
pthread_mutex_unlock(&hardware_lock);
然后你可以让你的信号处理线程获得锁定,重置硬件状态并调用exit
而不用释放锁定。 exit
调用将终止所有线程,并且由于锁定被保持,因此在终止之前没有其他线程可以使硬件混乱。
如果您有多个线程都在处理整个硬件状态的离散部分,您可以为每个状态部分创建一个单独的锁。然后让您的信号处理线程获取锁的所有,然后再设置最终硬件状态并调用exit
。由于在普通操作中,只有一个线程试图访问状态的每个离散部分,因此附加锁定不应对性能产生可测量的影响。
另一件事。我不认为它是准确的"因为我没有使用信号掩码,主线程将处理信号。"来自pthreads(7)
:
根据POSIX.1,过程导向信号(例如使用kill(2)发送)应该由过程中任意选择的一个线程处理。
这意味着应该使用pthread_sigmask
来确保SIGTERM
定向到主线程。