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 对接收它的进程会立即致命,并且无法被捕获或处理。

这就是为什么您应该只将它用作最后的手段,当进程没有响应更礼貌的关闭请求时。您的父进程应首先向子进程发送 SIGINTSIGTERM 之类的内容,并且只有在它们未在合理的时间内退出时才重置为 SIGKILL

SIGINTSIGTERM 之类的信号可能仍会导致子系统调用返回 EINTR,但您可以处理该问题并重试调用并让它在退出前完成。

【讨论】:

我应该说清楚——执行“SIGKILL”的代码在一个共享库中,我对更改持谨慎态度。我想过改变使用的信号,但我真的不能。似乎在父线程向子线程发送 SIGKILLS 之前,它应该发送一个不同的信号(SIGHUP?)来指示它即将关闭它们,然后等待子线程回复他们已经完成关闭下来,然后发送 SIGKILL。

以上是关于System V msg_send 被 SIGKILL 中断的主要内容,如果未能解决你的问题,请参考以下文章

twemproxy发送流程探索——剖析twemproxy代码正编

System V ABI的红区是如何实现的

System V 信号量

System.Web.HttpUtility VS System.Net.WebUtility

system v和posix的共享内存对比

System V IPC 中对密钥的需求