信号处理 - 异步功能和多线程应用程序,信号堆栈

时间:2012-03-04 23:50:00

标签: c operating-system kernel signals

有人可以解释为什么我们不应该从信号处理程序调用非异步函数?就像在使用这些函数调用时破坏程序的确切步骤序列一样。 并且,信号总是在单独的堆栈上运行吗?如果是这样,它是一个单独的上下文,还是在信号线程的上下文中运行? 最后,在多线程系统的情况下,当执行信号处理程序并发出一些其他线程并调用相同的信号处理程序时会发生什么? (我正在努力深入了解信号及其应用)

2 个答案:

答案 0 :(得分:2)

当进程收到信号时,它将在进程的上下文中处理。您应该只在信号处理程序中使用异步安全函数或可重入函数。例如,您不能在信号处理程序中调用malloc()或printf()。原因是:

*)让我们假设您收到信号后,您的进程正在malloc中执行。因此全局堆数据结构处于不一致状态。现在,如果从信号处理程序内部获取堆锁并进行更改,则会进一步使堆不一致。

*)另一种可能性是,如果您的进程在收到信号时已获取堆锁,然后从信号处理程序调用malloc(),它会看到锁被保持并等待无限获取锁(无限期,因为可以释放锁的线程在信号完全处理之前不会运行。)

2)信号在流​​程的上下文中运行。至于信号堆栈,你可以看看这个SO答案 - > Do signal handers have a separate stack?

3)至于获取相同信号的多个实例,您可以查看此链接 - > Signal Handling in UNIX Rumple Stiltskin很好地回答了这个问题。

答案 1 :(得分:0)

我知道一些Solaris。所以我正在使用它来获取详细信息。 LWP == Solaris用于“线程”,如pthreads。

像SIGILL这样的陷阱信号被传递到导致陷阱的线程。异步信号被传递到第一个活动线程(LWP),或者没有阻塞该信号的进程。名为aslwp()的内核模块遍历进程头表(已关联LWP),寻找第一个可能接收异步信号的候选者。

信号堆栈存在于内核中。我不知道是什么/如何回答您的信号堆栈问题。 一个过程可能有几个未决信号。这是你的意思吗?

发往进程的每个信号都保持在那里,直到进程将上下文(或被强制)切换到活动状态。这部分是因为当交换进程上下文并且进程没有执行任何操作时,通常不会产生陷阱。你当然可以招致异步信号。但如果无法运行,该过程不能对任何信号“做任何事情”。因此,此时内核将上下文交换回活动状态,并通过aslwp()传递信号。

实时信号表现不同,我让它保持不变。

试试这个:

developers.sun.com/solaris/articles/signalprimer.html
相关问题