【发布时间】:2018-09-20 20:25:09
【问题描述】:
我正在编写一个使用fork() 和exec() 运行外部程序的库。
我的库中的代码作为单独的线程运行。
库线程需要在fork出的进程上waitpid()才能知道子进程的退出码。
不幸的是,如果使用我的库的应用程序为SIGCHLD 注册了信号处理程序,waitpid() 调用将返回错误ECHILD。
作为一个对应用程序影响最小的库,我该如何处理? 我本质上希望孩子保持僵尸状态,并控制何时收割。
我可以将自己与应用程序决定做的事情隔离开来吗?
我可以以某种方式劫持信号处理程序并在我的waitpid 完成后将其放回吗?
【问题讨论】:
-
您可以分叉您的自己的 进程来处理您自己的进程处理,并让库通过管道或IPC 之类的方式与独立进程通信。然后您还可以安装自己的信号处理程序,例如你自己的
SIGCHLD而不是只依赖waitpid。 -
第二。 Unix 域数据报套接字通常对此很有用。 Unix 域套接字允许您使用辅助消息将文件描述符(例如与分叉的孙进程之间的管道描述符)传递回父进程。 Unix 域数据报消息不会重新排序,并保留消息边界(因此具有足够大缓冲区的接收将始终接收完整消息);这些特性使通信简单而健壮。对于这种方法,您甚至可能不需要单独的线程;辅助进程就足够了。
-
这是 Unix fork/wait 模型的一个古老问题,我不确定是否有任何简单的解决方案。
-
是的,看起来确实是一个复杂的问题。感谢您的回复!由于我的库被一组具有已知功能的非常受控的用户使用,我只是想说“不要注册信号处理程序”。
-
据我了解,标准的
system()函数也存在同样的问题。