我有一个有趣的(至少对我而言)问题:在某些情况下,我无法设法找到一种可靠且可移植地获取有关孙进程的信息的方法。我有一个应用程序,AllTray ,我正试图在某些奇怪的情况下开始工作,在这些情况下,它的子进程产生了一个 child 然后死了。 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,至少在 Linux 系统上,它不适用于 setuid/setgid GUI 应用程序。一般来说,我觉得这不是个好主意,而且感觉很老套。
所以,我希望有人知道如何做到这一点,或者如果依赖像 LD_PRELOAD
这样的机制的想法真的是我没有修补内核的唯一选择(这是不会发生的)。
最佳答案
您可以调查使用 process groups 的可能性跟踪过程组。进程组是一个属性(只是一个数字),您可以在 fork 之前设置它,然后子进程会自动继承它。
AllTray 可以为每个使用它启动的应用程序创建一个新的进程组。您可以向进程组的所有成员发送信号。我想这里最有用的信号是 TERM 和 KILL,以终止在 AllTray 中管理的应用程序。
我不确定是否有方便的方法来确定进程组的所有成员是否已经退出。您可能不得不求助于遍历整个进程列表并为每个进程调用 getpgid
以查看进程组中是否还有剩余。
请注意,进程组不适用于自行创建新进程组的应用程序。但这种情况相对较少,您可能不需要担心此类应用程序。
关于linux - 如何可靠地跟踪 POSIX 系统上的子/孙进程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/979747/