如何可靠地跟踪POSIX系统上的子/孙进程?

时间:2009-06-11 07:18:11

标签: linux unix process posix

我有一个有趣的问题(至少对我而言):在某些情况下,我无法找到一种可靠且可移植地获取孙子进程信息的方法。我有一个应用程序,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>不会发生。)

1 个答案:

答案 0 :(得分:1)

您可以调查使用process groups跟踪进程组的可能性。进程组是一个属性(只是一个数字),您可以在分叉之前设置它,然后子进程会自动继承它。

AllTray可以为每个启动它的应用程序创建一个新的进程组。您可以向进程组的所有成员发送信号。我想这里最有用的信号是TERM和KILL,以便杀死在AllTray中管理的应用程序。

我不确定是否有方便的方法来确定流程组的所有成员是否已经退出。您可能不得不求助于浏览整个流程列表并为每个流程调用getpgid以查看流程组中是否还有剩余流程。

请注意,进程组不适用于自己创建新进程组的应用程序。但这种情况相对较少,您可能不必担心此类应用程序。