如何查找所有子进程?

发布于 2024-07-25 00:50:03 字数 134 浏览 4 评论 0原文

在我正在开发的一个基于 Linux 的项目中,我需要能够找到我的所有子进程。 每次启动都进行记录是不可行的——需要在事后找到它们。 这需要是纯 C 语言,我想在不阅读 /proc 的情况下完成它。 有谁知道如何做到这一点?

In a Linux-based project that I am working on, I need to be able to find all of my child processes. It is not feasible to record every time one is started -- they need to be found after the fact. This needs to be pure C, and I'd like to do it without reading /proc. Does anyone know how to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

不…忘初心 2024-08-01 00:50:03

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

正如手册页所述:

pid_t fork(void);

如果您能告诉我们为什么您认为它不可行,那将会有所帮助。

It is usually entirely feasible to record child processes every time you start one. conveniently, the parent process is passed the pid value of the child process as the return value of the fork call which creates it.

As the man page says:

pid_t fork(void);

It would help if you could tell us why you think it isn't feasible.

债姬 2024-08-01 00:50:03

我发现您的评论认为记录进程的创建是不可行的,这很奇怪,但如果您真的不能(可能是因为您不知道将创建多少个进程并且不想保留重新分配内存),那么我可能会打开所有与 glob /proc/[1-9]*/status 匹配的文件,并查找显示 的行>PPid: 其中 是我的进程 ID。

I find your comment that it is not feasible to record the creation of processes to be odd, but if you really can't (possibly because you don't know how many will be created and don't want to have to keep reallocing memory), then I would probably open all of the files that match the glob /proc/[1-9]*/status and look for the line that says PPid: <num> where <num> was my process id.

故人爱我别走 2024-08-01 00:50:03

你可以使用 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;
}


You could use popen

Something like. (Hopefully the syntax is close enough)

#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;
}


薯片软お妹 2024-08-01 00:50:03

你可以尝试这个

#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 给出父进程具有 PID 的所有子进程的 pid。 现在,我们可以使用getpid()获取父进程的PID,它返回pid_t并隐式转换为整数。 sprintf() 将其转换为字符串,然后将结果与 str 连接以获得由 system() 执行的完整命令。

You could try this

#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);

NOTE: This piece of code needs to be in the parent process

Basically ps -o pid --ppid <parent_id> gives the pid of all child processes whose parent has PID <parent_id>. Now, we can get the parent's process's PID by using getpid(), which returns pid_t and is implicitly converted to an integer. sprintf() converts it into a string and we concatenate the result with str to get the complete command which is executed by system().

与酒说心事 2024-08-01 00:50:03

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

You could parse a process list (ps -ax?) that included the parent process ID. This could probably be done with a simple shell script.

(り薆情海 2024-08-01 00:50:03

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

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

If you're trying to get all child processes for the very specific purpose of waiting for them to exit, you can use waitpid(-1, ...):

while (true) {
  // Wait for any child exiting
  int child_status;
  const int child_pid = waitpid(-1, &child_status, 0);
  // check child_status
}
⊕婉儿 2024-08-01 00:50:03

如果您想跟踪 fork 事件并提取子 pid 来进行调试,有多种方法可以实现,包括:

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

If you want to trace fork events and extract child pids for debugging purposes, there are a number of ways to do that, including:

  • Using GDB
  • using strace
  • Using systemtap
  • Using kernel event connectors (not sure what these are exactly)
私野 2024-08-01 00:50:03

此存储库中的代码需要调整为用纯 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 的源代码,然后在构建后链接到它。

The code in this repository will need to be adjusted to be written in plain C to meet your request, and if you are ok with doing so, if you remove all the unused functionality from my repository within your project, it shouldnt be that hard to translate into plain C.

But this is more useful for people looking to support multiple platforms and/or who prefer C++.

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

Returns a string with each child process id separated by a pipe "|" character as the delimiter.

Ubuntu and debian users need libprocps-dev installed for missing headers.

sudo apt-get install libprocps-dev libx11-dev

The libx11-dev dependency is optional because all X11 code in the source can be omitted and the question here will still be answered, so if you need wayland and no X11 support you should remove X11 related code as it's unrelated to this question anyway.

For those who actually like/need X11 and/or C++ this will work out of the box on Windows, Mac, Linux, and FreeBSD. Support for other BSD's is not as easily viable thanks to relying on the libutil dependency. But it just uses sysctl() internally so in theory you should be able to compile the source code for libutil on the other BSD's available from FreeBSD's github repository, and then link to it after you have built it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文