前言
我有一个使用 Boost.Asio 运行的多线程应用程序。整个应用程序只有一个 boost::asio::io_service
,并且所有的操作都由一组线程在其中完成。有时需要使用 fork 和 exec 来生成子进程。当子进程终止后,我需要调用 waitpid 来检查退出代码并收集 zombie 进程。我最近使用了新增的 boost::asio::signal_set
,但是在一些仍在使用 Linux 2.4.* 内核的古老系统中遇到了问题。在旧版本的 Linux 内核下,线程实际上是进程的一种特殊情况,因此如果一个子进程是由一个线程生成的,另一个线程将无法使用 waitpid
系列系统调用等待它。Asio 的 signal_set 会将信号处理程序投递到 io_service
,任何运行该服务的线程都可以运行该处理程序,这对我的情况是不合适的。所以我决定用旧的好方法 signal/sigaction 来处理信号 - 所有线程都有相同的处理程序,该处理程序调用 waitpid
。那么就出现了另一个问题:
问题
当处理程序捕获信号并成功等待进程时,如何从处理程序中“发布”到我的 io_service
中?我认为,明显的 io_service::post()
方法是不可能的,因为如果信号在错误的时间到达,它可能会造成 io_service
内部互斥锁死锁。唯一想到的方法是使用一些管道或 socketpair 将通知写入其中,然后在另一端使用 async_wait
处理,就像在处理 poll()
事件循环中的信号时一样。
还有更好的解决方案吗?