如何找到所有子进程?

时间:2009-06-17 21:13:58

标签: c linux process

在我正在开发的基于Linux的项目中,我需要能够找到所有子进程。每次开始记录都是不可行的 - 它们需要在事后发现。这需要是纯C,我想在没有读/ proc的情况下这样做。有谁知道怎么做?

8 个答案:

答案 0 :(得分:5)

你可以使用popen

喜欢的东西。 (希望语法足够接近)

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    FILE *fp = popen("ps -C *YOUR PROGRAM NAME HERE* --format '%P %p'" , "r");
    if (fp == NULL)
    {
        printf("ERROR!\n");
    }

    char parentID[256];
    char processID[256];
    while (fscanf(fp, "%s %s", parentID, processID) != EOF)
    {
         printf("PID: %s  Parent: %s\n", processID, parentID);

         // Check the parentID to see if it that of your process
    }

    pclose(fp);

    return 1;
}


答案 1 :(得分:5)

每次启动子进程时,记录子进程通常是完全可行的。方便的是,父进程传递子进程的pid值作为创建它的fork调用的返回值。

正如手册页所说:

pid_t fork(void);

如果您能告诉我们您认为不可行的原因,那将会有所帮助。

答案 2 :(得分:4)

我发现你的评论认为将进程的创建记录为奇怪是不可行的,但是如果你真的不能(可能是因为你不知道将创建多少进程并且不想拥有保留realloc内存),然后我可能会打开与glob /proc/[1-9]*/status匹配的所有文件,并查找PPid: <num>行,其中<num>是我的进程ID

答案 3 :(得分:4)

你可以试试这个

#include<string.h>
#include <sys/types.h>
#include <unistd.h>

char str[50] = "ps -o pid --ppid ";
char ppid [7];
sprintf(ppid,"%d",getpid());
strcat(str,ppid);
system(str);

注意:这段代码需要在父进程中

基本上ps -o pid --ppid <parent_id>给出父级具有PID <parent_id>的所有子进程的pid。现在,我们可以使用getpid()获取父进程的PID,返回pid_t并隐式转换为整数。 sprintf()将其转换为字符串,我们将结果与str连接起来,以获取由system()执行的完整命令。

答案 4 :(得分:1)

您可以解析包含父进程ID的进程列表(ps -ax?)。这可能是通过简单的shell脚本完成的。

答案 5 :(得分:0)

如果要跟踪fork事件并提取子pid以进行调试,有很多方法可以做到这一点,包括:

  • 使用GDB
  • 使用strace
  • 使用systemtap
  • 使用内核事件连接器(不确定这些是什么)

答案 6 :(得分:0)

如果您尝试将所有子进程用于等待它们退出的特定目的,则可以使用waitpid(-1,...):

while (true) {
  // Wait for any child exiting
  int child_status;
  const int child_pid = waitpid(-1, &child_status, 0);
  // check child_status
}

答案 7 :(得分:0)

此存储库中的代码将需要进行调整,以使用纯C语言编写,以满足您的要求,如果可以,如果您从项目中我的存储库中删除了所有未使用的功能,则不应很难翻译成普通的C。

但这对于希望支持多个平台的用户和/或喜欢C ++的人来说更有用。

参见函数pids_from_ppid(ppid) https://github.com/time-killer-games/enigma-dev/blob/548dc16e96a2a32f8ad9045a4ee18b0206516e62/ENIGMAsystem/SHELL/Universal_System/Extensions/ProcInfo/procinfo.h#L101

返回一个字符串,每个子进程ID均由竖线“ |”分隔字符作为分隔符。

Ubuntu和debian用户需要安装libprocps-dev才能缺少标头。

sudo apt-get install libprocps-dev libx11-dev

libx11-dev依赖项是可选的,因为可以省略源代码中的所有X11代码,并且仍然可以回答此处的问题,因此,如果您需要Wayland并且没有X11支持,则应删除与X11相关的代码,因为它与该问题无关无论如何。

对于真正喜欢/需要X11和/或C ++的用户,这将在Windows,Mac,Linux和FreeBSD上开箱即用。由于依赖libutil依赖项,因此对其他BSD的支持并不那么容易实现。但是它只是在内部使用sysctl(),因此从理论上讲,您应该能够在FreeBSD的github存储库中的其他BSD上编译libutil的源代码,然后在构建它之后链接到它。