0

我不认为这是重复的。关于调用信号处理程序时其他线程会发生什么,我有一个非常具体的问题。

我有一个使用硬件的多线程程序。在获得 SIGTERM(来自父进程)时,我希望信号处理程序将硬件状态设置为给定状态,然后退出(1)。我明白,由于我没有使用信号掩码,主线程将处理信号。但它是一个多处理器系统(树莓派),其他线程都以相对于 main 的高优先级运行。他们可能睡着了,但他们也可能正在触摸硬件。

如果所有其他线程在信号到达时冻结,我很好 - 我直接从信号处理程序调用 exit() 并且其他线程将永远不会再次运行。但是,如果它们可以独立运行,那么在我在处理程序中设置所需状态之后,但在我退出之前,它们可能会对硬件大惊小怪。而且我找不到描述效果的文档。如果“冻结除信号处理程序之外的所有内容”不是默认设置,有没有办法获得这种行为?

我可以重新设计代码,将所有硬件处理放在一个线程中,并让该线程处理中断,但这很不方便——我现在拥有的线程布局做了很好的分工,每个线程都知道它可以接触什么硬件以及何时接触。我宁愿不重新设计。

4

1 回答 1

3

其他线程将在信号处理线程运行时继续运行。我不知道任何冻结一切的机制。

但是,如果您有多个线程来操作硬件,那么您似乎应该有某种互斥机制。有效:

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定向到主线程。

于 2017-02-28T18:03:33.937 回答