System V msg_send 被 SIGKILL 中断
Posted
技术标签:
【中文标题】System V msg_send 被 SIGKILL 中断【英文标题】:System V msg_send interrupted by SIGKILL 【发布时间】:2013-01-22 21:18:34 【问题描述】:我有一个像这样工作的多进程应用程序...
有一个父进程。父进程查询数据库以查找工作,然后派生子进程来处理该工作。孩子们通过 System V 消息队列与父母交流,以表明他们已经完成了他们的工作。当父进程收到该消息时,它会更新数据库以指示工作已完成。
这工作正常,但我正在努力处理被杀死的父进程。
父母收到一个 SIGINT(来自 CTRL-C),然后向每个孩子发送 SIGKILL。如果子进程在接收到该信号时正在阻塞 Sys V 消息队列写入,则写入会被信号“中断”并且阻塞被取消,并且父进程永远不会知道子进程的工作已经完成,并且数据库永远不会更新.
这意味着下次我运行脚本时,它将重新运行阻塞在 System V 队列写入上的任何工作。
我还没有一个解决方案的好主意。理想情况下,我希望能够强制队列写入保持阻塞状态,即使它收到 SIGKILL 但我认为这是不可能的。
【问题讨论】:
【参考方案1】:根据定义,SIGKILL
对接收它的进程会立即致命,并且无法被捕获或处理。
这就是为什么您应该只将它用作最后的手段,当进程没有响应更礼貌的关闭请求时。您的父进程应首先向子进程发送 SIGINT
或 SIGTERM
之类的内容,并且只有在它们未在合理的时间内退出时才重置为 SIGKILL
。
SIGINT
和 SIGTERM
之类的信号可能仍会导致子系统调用返回 EINTR
,但您可以处理该问题并重试调用并让它在退出前完成。
【讨论】:
我应该说清楚——执行“SIGKILL”的代码在一个共享库中,我对更改持谨慎态度。我想过改变使用的信号,但我真的不能。似乎在父线程向子线程发送 SIGKILLS 之前,它应该发送一个不同的信号(SIGHUP?)来指示它即将关闭它们,然后等待子线程回复他们已经完成关闭下来,然后发送 SIGKILL。以上是关于System V msg_send 被 SIGKILL 中断的主要内容,如果未能解决你的问题,请参考以下文章
twemproxy发送流程探索——剖析twemproxy代码正编