2015-07-10 69 views
4

我正在Linux上运行用C编写的多线程应用程序。
当其中一个线程收到信号并且它们都没有阻塞它时,所有线程都停止了吗?

要停止执行,我发送SIGINT并从信号处理程序调用一些清理例程,最后请致电exit(0)

当处理程序执行清理例程时,其他线程仍在运行还是可能运行(上下文切换)?

+2

您不希望在信号处理程序中调用'exit()'来回,因为它不是通过异步信号安全保证的。改为调用'_exit()'。或者甚至更好的是不要从信号处理程序中结束程序,而是通过让所有线程正常结束来执行优雅关闭。作为参考:http://man7.org/linux/man-pages/man7/signal.7.html – alk

回答

6

处理的信号不会导致暂停在执行信号处理程序期间的其他线程。此外,从信号处理程序中调用大多数需要清理的函数(包括即使是exit!)也是不安全的,除非您可以确保它不会中断异步信号不安全的函数。

你应该做的只是简单地存储一个事实,即以某种异步信号安全的方式接收到SIGINT,并让该程序作为其正常执行流程的一部分,在信号处理程序之外执行。然后,您可以正确地与其他线程同步(使用互斥锁,条件变量等)以实现正确,安全的关闭。理想的方法不是安装信号处理程序,而是封锁所有信号,并在专门的信号处理线程中调用sigwaitinfo来接受信号。

2

是的,信号传递到一个线程,以未指定的方式选择。尽管如此,只有不阻断信号的线程才会被考虑。如果所有线程阻塞信号,它将保持排队,直到一个线程解除阻塞。

(所以,如果你让所有线程阻塞信号,就可以使用该信号作为确定性,进程间的同步机制,例如使用sigwait

+0

但是,如果他们不阻止信号,其他人可能会运行,而收到信号的人正在处理它?因为我有一个日志,并且在信号处理程序打印“退出”后由不同的线程引起的打印。 – Pepedou

+0

是的,不接收信号的线程没有做任何特殊的事情。他们不知道另一个线程已收到信号。 –

+2

我认为这个答案错过了这个问题的观点。 –

相关问题