【问题标题】:Does main() get paused during signal handling?main() 是否在信号处理期间暂停?
【发布时间】:2015-05-25 16:21:22
【问题描述】:

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

调用信号处理程序时,main() 是否暂停,直到处理程序完成其工作? 如果是这样并且处理程序调用了 exit(),main() 执行是否被中止(立即和原子地)? 如果不是这样,不处理 SIGTERM(来自连接的 POV)是一个“好主意”吗?

更新:为什么要暂停 main():比方说:

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

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

【问题讨论】:

  • 我不明白,为什么main() 会暂停?您需要处理信号,完成后,即关闭与数据库的连接,您调用exit() 就是这样,为什么main() 需要暂停? 决定何时exit()该程序!
  • main 就是你的程序开始运行的地方。如果您调用任何其他函数,则 main() 在该函数运行时“暂停”。包括信号处理程序...
  • 您并不想从信号处理程序中调用exit(),至少如果您想确保程序干净地关闭则不会。 exit() 不保证是异步信号保存。请改用_exit()。有关详细信息,请参阅man 7 signal。是的,处理信号的进程在处理信号期间会被中断。
  • @iharob 查看更新。
  • 引用我之前的评论:将“process”替换为“thread

标签: c database connection posix daemon


【解决方案1】:

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

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

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

尽管干净地关闭数据库连接的愿望是可以理解的,但数据库必须能够适应不干净地终止的连接。客户端在意外时刻崩溃,网络连接可能失败;面对此类事件,数据库必须是稳健的。接收 SIGTERM 的客户端只是这些可能性的长列表之一,最好简单地依赖数据库服务器正确处理关闭。

【讨论】:

  • 如果数据库“将处理它”并且处理程序无论如何都要 _Exit(),我是否必须关心它调用 free() 或类似方法时会发生什么?
  • @AlexanderAleksandrovičKlimov:假设您对free 的调用导致无限循环。信号处理程序永远不会返回,因此不会对 SIGTERM 进行操作。如果发送 SIGTERM 是因为机器无论如何都要关闭,那可能不是问题,尽管额外的负载可能会抑制其他清理功能,但在一般情况下,让默认处理程序 _exit 会更好。跨度>
猜你喜欢
  • 2011-09-02
  • 2016-03-21
  • 1970-01-01
  • 2021-06-15
  • 2012-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多