在Linux中检测进程是否为僵尸进程

3
我们可以通过Shell命令行检测某个进程是否为僵尸进程。
ps ef -o pid,stat | grep <pid> | grep Z

为了在我们的C/C++程序中获取这些信息,我们使用popen(),但是我们希望避免使用popen()。是否有一种方法可以在不产生额外进程的情况下获得相同的结果?
我们正在使用Linux 2.6.32-279.5.2.el6.x86_64。
1个回答

8
您需要使用 proc(5) 文件系统。它内部的文件(如/proc/1234/stat)访问速度非常快(因为不涉及任何物理I/O)。
您可能想要从/proc/1234/stat获取第三个字段(该字段可被所有人读取,但应按顺序读取,因为它是不可寻址的)。如果该字段为Z,则进程pid 1234为僵尸进程。
无需fork一个进程(例如使用popensystem),在C中您可以编写:
pid_t somepid;
// put the process pid you are interested in into somepid

bool iszombie = false;
// open the /proc/*/stat file
char pbuf[32];
snprintf(pbuf, sizeof(pbuf), "/proc/%d/stat", (int) somepid);
FILE* fpstat = fopen(pbuf, "r");
if (!fpstat) { perror(pbuf); exit(EXIT_FAILURE); };
{
  int rpid =0; char rcmd[32]; char rstatc = 0;
  fscanf(fpstat, "%d %30s %c", &rpid, rcmd, &rstatc); 
  iszombie = rstatc == 'Z';
}
fclose(fpstat);

考虑使用procpslibproc,请参见此答案
(您还可以阅读/proc/1234/status的第二行,但这可能更难在C或C ++代码中解析)
顺便说一下,我发现/proc/中的stat文件具有奇怪的格式:如果您的可执行文件名称中同时包含空格和括号(虽然允许,但令人讨厌),则解析/proc/*/stat文件将变得棘手。

谢谢,但是即使在这种情况下我们也需要在C/C++程序中使用popen()。我需要避免使用popen()。 - Alex
@Alex:你不需要使用popen()来访问/proc,只需使用普通的open()fopen()即可。 - Dietrich Epp
如果可执行文件的权限是700?而且这个可执行文件不是我的吗? - Alex
是的,即使对于不属于你的系统进程,/proc/1234/stat 文件也是全局可读的。在某些系统(如SELinux)中,您无法阅读它时,您不应该关心该进程(因为您无法做任何事情)。 - Basile Starynkevitch
看起来,即使可执行文件的权限为700且可执行文件不是我的,它似乎也能正常工作。谢谢。 - Alex
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接