我正在开发一个POSIX守护进程,它不时从数据库中读取。 我希望在SIGTERM到达时关闭连接(例如,当系统关闭时)。
当调用信号处理程序时,main()是否暂停,直到处理程序完成其作业? 如果是这样并且处理程序调用exit(),那么main()执行是否中止(立即和原子)? 如果不是这样,那么仅仅处理SIGTERM(来自连接的POV)是一个“好主意”吗?
更新:为什么要暂停main():让我们说:
这将导致取消引用无效指针(或至少在关闭连接的操作中)。
答案 0 :(得分:2)
信号中断过程执行;它们不是并行执行的。因此,如果进程中只有一个线程,则在信号处理程序执行时它将被挂起。 (如果进程是多线程的,则只会中断一个线程,其他线程将继续执行。)
但是,在中断过程中几乎没有关于过程状态的保证。在内部数据结构处于不一致状态的点处执行标准库函数期间可能会中断它。在执行信号处理程序期间,可能只调用少量系统接口(完整列表为here);特别是,可能无法调用malloc
和free
等内存管理功能,关闭数据库连接很可能涉及调用free
。 close
和shutdown
是异步信号安全的。 exit
不是(但_exit
是)。
信号处理程序可以修改全局变量的值,可以定期轮询(这样的变量必须声明为volatile
),但确保主进程识别终止不是容易。
虽然可以理解干净地关闭数据库连接的愿望,但数据库必须能够适应不正确终止的连接。客户端在意外时刻崩溃,网络连接可能会失败;面对这种情况,数据库必须是健壮的。接收SIGTERM的客户端只是这些可能性的长列表之一,最好只依靠数据库服务器正确处理关闭。