信号处理

仅使用 C 标准的保证的信号处理程序的使用强加了在用户定义的信号处理程序中可以或不可以完成的各种限制。

  • 如果用户定义的函数在处理 SIGSEGVSIGFPESIGILL 或任何其他实现定义的硬件中断时返回,则 C 标准未定义该行为。这是因为 C 的接口不提供改变故障状态的方法(例如,在通过 0 划分之后),因此当返回程序时,处于与硬件中断发生之前完全相同的错误状态。

  • 如果调用用户定义的函数是调用 abortraise 的结果,则不允许信号处理程序再次调用 raise

  • 信号可以在任何操作的中间到达,因此通常不能保证操作的不可分割性,信号处理也不能很好地与优化一起工作。因此,信号处理程序中对数据的所有修改都必须是变量

    • 类型 sig_atomic_t(所有版本)或无锁原子类型(自 C11,可选)
    • 这是 volatile 合格的。
  • C 标准库中的其他函数通常不会遵守这些限制,因为它们可能会更改程序的全局状态中的变量。C 标准仅对 abort_Exit(自 C99),quick_exit(自 C11 以来),signal(对于相同的信号编号)和一些原子操作(自 C11 以来)提供保证。

如果违反了上述任何规则,则 C 标准未定义行为。平台可能具有特定扩展,但这些扩展通常不能在该平台之外移植。

  • 通常,系统有自己的异步信号安全功能列表,即可以从信号处理程序使用的 C 库函数。例如,通常 printf 就是这些功能之一。

  • 特别是 C 标准没有详细说明与其线程接口(自 C11)或任何特定于平台的线程库(如 POSIX 线程)的交互。这些平台必须自己指定这些线程库与信号的交互。