在有信号的情况下要注意什么

时间:2011-12-21 10:47:46

标签: c linux gcc x86 signals

我在应用程序were not always working as expected中看到了这些信号量。然后我被告知,当信号中断sem_wait呼叫时,可能会导致这种意外行为。

所以,我的问题是程序员在出现信号时需要注意什么。对于sem_wait,我们可以检查返回值,但对于所有非异步安全函数,这是否相同?当期待信号中断我们的代码时,我们还应该记住什么?

1 个答案:

答案 0 :(得分:2)

UNIX信号是一种蠕虫病毒,就是这么说的。

有关于系统调用和信号的2个阵营。

  • SysV / Posix语义:系统调用被信号中断,它们返回错误并将errno设置为EINTR
  • 如果发生信号,BSD语义系统调用会自动重启(好吧,其中大多数都是,有些不是,例如select / poll / sleep)。

当使用signal()时,默认值是上面两个中的一个,BSD系统和Linux默认为BSD语义,并且每个人[引用需要..]否则具有SysV语义。 (在Linux上,这取决于很多事情,例如用-std = c99编译给出SysV语义,-std = gnu99给出BSD语义。参见例如http://www.gnu.org/s/hello/manual/libc/Interrupted-Primitives.html

使用sigaction()安装信号处理程序时,可以选择SA_RESTART标志的语义。

基本上:

  • 如果可以提供帮助,请不要使用信号。
  • 如果可以,请使用BSD语义。
  • 在需要可移植并处理信号的代码上,您需要将每个系统调用包装在一个检查失败调用的循环中,检查errno是否为EINTR并再次执行系统调用(或根据捕获的内容执行某些操作)信号)。
  • 库调用可以使用信号,即使您的代码没有。
  • 系统调用一般来说,使用SysV / Posix语义,将返回-1并将errno设置为EINTR。但请阅读文档以了解错误情况。

编辑:编辑,因为我混淆了BSD与Sysv语义。