我有一个有趣的问题(至少对我而言):在某些情况下,我无法找到一种可靠且可移植地获取孙子进程信息的方法。我有一个应用程序,AllTray,我试图在某些奇怪的情况下工作,其子进程生成一个孩子,然后死亡。 AllTray的工作主要是将应用程序停靠到任务托盘,该任务托盘(通常)被指定为AllTray调用的命令行(即alltray xterm
将启动xterm,并在AllTray中管理它。)
大多数GUI软件都运行得很好。它在其窗口(或小部件库中)设置了_NET_WM_PID
属性,并且很好,因为_NET_WM_PID
== fork()
ed child。但是,在某些情况下(例如运行oowriter
或编写在KDE下运行的软件,如K3b),AllTray运行的子进程是一个包装器,无论是shell脚本(如在OO.o的情况下)或者是一个奇怪的程序fork()
和exec()
本身并且有效地背景本身,因为父进程很早就会死掉。
我有想法不收割我的子进程,以便在进程表中保留我的孙子进程的父进程ID,以便我可以通过从底部到顶部遍历来自它的家族树将它们链接回我。但这不起作用:一旦我的孩子进程死亡并变成僵尸,系统会认为我的孙子进程是一个孤儿,init
采用它。至少在Linux 2.6和NetBSD上就是这种情况;我认为它可能是常态,而POSIX似乎没有指明情况,所以我希望相反。
由于该方法不起作用,我考虑使用LD_PRELOAD
并拦截我的子进程'调用fork()
,并将信息传递回我的父进程。但是,我担心它不会像理想的解决方案那样可移植,因为不同的系统对动态链接器如LD_PRELOAD
这样的事情有不同的规则。它不适用于setuid / setgid GUI应用程序,或者没有helper库也是setuid或setgid,至少在Linux系统上是这样。一般来说,它对我来说闻起来像个坏主意,并且感觉相当hackish。
所以,我希望有人知道如何做到这一点,或者依赖像LD_PRELOAD
这样的机制的想法是否真的是我没有修补内核的唯一选择(这是< em>不会发生。)
答案 0 :(得分:1)
您可以调查使用process groups跟踪进程组的可能性。进程组是一个属性(只是一个数字),您可以在分叉之前设置它,然后子进程会自动继承它。
AllTray可以为每个启动它的应用程序创建一个新的进程组。您可以向进程组的所有成员发送信号。我想这里最有用的信号是TERM和KILL,以便杀死在AllTray中管理的应用程序。
我不确定是否有方便的方法来确定流程组的所有成员是否已经退出。您可能不得不求助于浏览整个流程列表并为每个流程调用getpgid
以查看流程组中是否还有剩余流程。
请注意,进程组不适用于自己创建新进程组的应用程序。但这种情况相对较少,您可能不必担心此类应用程序。