main() 在信号处理期间是否暂停?

Does main() get paused during signal handling?

我正在开发一个 POSIX 守护程序,它会不时地从数据库中读取数据。 我想在 SIGTERM 到达时关闭连接(例如,当系统关闭时)。

调用信号处理程序时,main() 是否暂停,直到处理程序完成其工作? 如果是这样并且处理程序调用 exit(),main() 执行是否中止(立即且原子地)? 如果不是这样,是否只是 "good idea" 不处理 SIGTERM(来自连接的 POV)?

更新: 为什么要暂停 main():假设:

  1. SIGTERM 到达并调用信号处理程序。它关闭连接并释放内存。
  2. 在那之后,未暂停的 main() 表示是时候从数据库中获取数据了。

这将导致对无效指针的取消引用(或至少在对已关闭连接的操作中)。

信号中断进程执行;它们不并行执行。所以如果进程中只有一个线程,它会在信号处理程序执行时被挂起。 (如果是多线程进程,只有一个线程会被中断,其他线程继续执行。)

但是,对于进程被中断时的状态几乎没有任何保证。它可能会在执行标准库函数期间在内部数据结构处于不一致状态时中断。在执行信号处理程序期间,可能只调用少量系统接口(完整列表here);特别是内存管理函数,如 mallocfree 可能不会被调用,关闭数据库连接很可能会调用 freecloseshutdown 是异步信号安全的。 exit 不是(但 _exit 是)。

信号处理程序可以修改全局变量的值,可以定期轮询(此类变量必须声明 volatile)但要确保主进程能够识别终止不容易。

虽然干净地关闭数据库连接的愿望是可以理解的,但数据库必须对不干净地终止的连接具有弹性。客户端在意外时刻崩溃,网络连接可能失败;面对此类事件,数据库必须稳健。收到 SIGTERM 的客户端只是这些可能性的一长串中的一种,最好只依赖数据库服务器正确处理关闭。