无法为 sigchld_handler 内的 pid 获取 pgid()

Unable to getpgid() for a pid inside sigchld_handler

在我正在开发的 shell 中,我通过分叉 children 来执行管道中的每个 child 来执行一组命令 A | B | C。这 3 child 人的 PGID 都与第一个 child 的相同。即PID为x,y,z的3children的PGID=x。所有 3 个命令的执行 运行 完美。在 SIGCHLD 信号处理程序 sigchld_handler() 中,我等待计算 children 终止的数量,一旦它是 3,我得到 PGID 以获取要从 JobList 中删除的作业数据。但是,所有 3 个 PID x, y, z 的函数 getpgid() returns -1。即 getpgid(x), getpgid(y), getpgid(z) 所有 return -1 with errno 3 (ESRCH).

在 parent 进程中使用 setpgid() 将 pgid 设置为 children 时,getpgid() 工作得很好并且 returned x。此问题仅发生在信号处理程序中。你能指导我在信号处理程序中获取 pidpgid 吗?

这里是信号处理代码:

void sigchld_handler(int s) {

    \declarations
    pid_t pid, pgid;
    .
    .
    .

    while ((pid = waitpid(-1, &status, WNOHANG | WUNTRACED)) > 0) {
        pgid = getpgid(pid);   // pgid = -1, but should return x.
        .
        .
        .
    }
}

while in main(), 在 parent process, after I do:

.
.
setpgid(x, x);
setpgid(y, x);
setpgid(z, x);
.
.


getpgid(x) returns x
getpgid(y) returns x
getpgid(z) returns x

非常感谢任何帮助。

谢谢。

SIGCHLD 是子进程终止时收到的信号。这有点道理,你不能为一个死进程请求 PGID ... 请注意,在您已经使用 waitpid 收割进程后,您仅 运行 它,因此系统无法找到请求的 PID 以从中提取 PGID。

您得到的错误 (3) 是 ESRCH:

#define ESRCH        3  /* No such process */

这只会加强这一点 - PID 不再有效。 我建议您创建一个从 PID 到 GID 的内部映射,并在您的进程内部进行查找。