我搜索了很多但没有找到解决方案。所以这可能是一个愚蠢的问题。
waitpid的格式为
pid_t waitpid (pid_t pid, int *status, int options)
pid 参数准确指定要等待的一个或多个进程。其价值观分为四个阵营:
< -1
Wait for any child process whose process group ID is equal to the absolute value of this value.
-1
Wait for any child process. This is the same behavior as wait( ).
0
Wait for any child process that belongs to the same process group as the calling process.
> 0
Wait for any child process whose pid is exactly the value provided.
现在的问题是,如果父级和子级具有不同的组 id,并且子级的组 id 为 1,该怎么办。如何为该特定子级使用 waitpid?因为我们不能使用 -1 它会告诉等待任何孩子。
答案1
你只能等待你的进程中的孩子。
如果子进程更改了它的进程组 ID,则新的进程组 ID 可以用作带有 的负数waitpid()
。
顺便说一句:该函数waitpid()
自 1989 年以来已被弃用。现代函数是:waitid()
并且它支持您喜欢的功能:
waitid(idtype, id, infop, opts)
idtype_t idtype;
id_t id;
siginfo_t *infop; /* Must be != NULL */
int opts;
如果您想等待进程组,请使用:
waitid(P_PGID, pgid, infop, opts);
因此,如果进程组 ID 1 下确实有一个进程,请调用:
waitid(P_PGID, 1, infop, opts);
但由于init
已经使用了此进程组 ID,因此您需要成为该init
进程才能在 pgid 1 下拥有子进程。
然而,如果您所在的平台不是waitid()
作为系统调用实现而是作为过时的waitpid()
.
其优点waitid()
是:
允许明确指定要等待的内容(例如 P_PID P_PGID P_ALL)
将子进程中参数的所有 32 位返回
exit(2)
给父进程。允许使用标志等待:
WNOWAIT
不会收获子进程并将其保留在进程表中以供稍后使用。
顺便说一句: 中的 siginfo_t 指针waitid()
与 的信号处理函数的第二个参数相同SIGCHLD
。
答案2
当子进程的进程组 ID 为 时,您会遇到一些麻烦1
。
进程组主要用于运行前台和后台进程(管道)的 shell。通常,当启动一个新的进程组时,它会从第一个进程的进程ID中获取进程组ID。您不会获得 PID 1 的子级,因此您也不会获得 PGID 1 的子级。
该setpgid()
调用允许将进程从一个进程组移动到另一个进程组,但它们仍然需要是同一(登录)会话的一部分,因此您也不能以这种方式将进程移动到 PGID 1。
如果您有一个以 PID 1 运行的 shell,那么它也可能具有 PGID 1。但只要 shell 更改其子级的 PGID,它们就会有不同的 PGID。