在我正在开发的基于Linux的项目中,我需要能够找到所有子进程。每次开始记录都是不可行的 - 它们需要在事后发现。这需要是纯C,我想在没有读/ proc的情况下这样做。有谁知道怎么做?
答案 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以进行调试,有很多方法可以做到这一点,包括:
答案 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的源代码,然后在构建它之后链接到它。