如何查找所有子进程?
在我正在开发的一个基于 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
每次启动子进程时记录子进程通常是完全可行的。 方便的是,父进程将子进程的 pid 值作为创建子进程的 fork 调用的返回值传递。
正如手册页所述:
如果您能告诉我们为什么您认为它不可行,那将会有所帮助。
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:
It would help if you could tell us why you think it isn't feasible.
我发现您的评论认为记录进程的创建是不可行的,这很奇怪,但如果您真的不能(可能是因为您不知道将创建多少个进程并且不想保留
重新分配内存),那么我可能会打开所有与 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
realloc
ing memory), then I would probably open all of the files that match the glob/proc/[1-9]*/status
and look for the line that saysPPid: <num>
where<num>
was my process id.你可以使用 popen
之类的东西。 (希望语法足够接近)
You could use popen
Something like. (Hopefully the syntax is close enough)
你可以尝试这个
注意:这段代码需要在父进程中
基本上
ps -o pid --ppid
给出父进程具有 PID的所有子进程的 pid
。 现在,我们可以使用getpid()
获取父进程的PID,它返回pid_t
并隐式转换为整数。sprintf()
将其转换为字符串,然后将结果与str
连接以获得由system()
执行的完整命令。You could try this
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 usinggetpid()
, which returnspid_t
and is implicitly converted to an integer.sprintf()
converts it into a string and we concatenate the result withstr
to get the complete command which is executed bysystem()
.您可以解析包含父进程 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.
如果您尝试获取所有子进程以等待它们退出的特定目的,则可以使用 waitpid(-1, ...):
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, ...):
如果您想跟踪 fork 事件并提取子 pid 来进行调试,有多种方法可以实现,包括:
If you want to trace fork events and extract child pids for debugging purposes, there are a number of ways to do that, including:
此存储库中的代码需要调整为用纯 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.