10

假设 pidX是进程组的领导者并X终止,但进程组中的其他进程仍在运行(以X它们的 pgid 作为其 pgid)。Linux 会阻止将值X作为 pid 分配给新进程吗?

我问这个是因为 POSIX 允许的故障条件setsid

[EPERM] 调用进程已经是进程组长,或者调用进程以外的进程组ID与调用进程的进程ID匹配。

对于使用“随机”触发的进程组(即 shell)的代码来说,这个错误似乎是一个不可恢复的条件,这使得它更加可恶。我会假设任何针对正常质量水平的实现都会避免X在它仍用作 pgid 时重新分配为 pid,但我无法在任何地方找到此文档。

4

2 回答 2

6

没问题,因为fork 保证

子进程 ID 也不应与任何活动进程组 ID 匹配。

并且fork是创建新流程的唯一方法。

于 2011-07-22T03:23:34.380 回答
5

Nemo 是正确的,POSIX 保证fork()不会重新使用现有的 PGID 作为 PID;然而,还有更多的故事。

流程组和流程组负责人也可以使用setpgid(). 以下示例代码导致存在一个等于当前进程的 PID 的进程组,当前进程不在该进程组中:

#define _XOPEN_SOURCE 500
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>

int main()
{
    pid_t pgrp_orig;
    pid_t child;
    int status;

    /* Fork so that we are not a process group leader */
    if (fork()) {
        /* Grandparent process */
        wait(&status);
        return 0;
    }

    /* Record our original process group, then start a new one */
    pgrp_orig = getpgrp();
    if (setpgid(0, 0))
        perror("setpgid");

    child = fork();

    if (!child) {
        /* Child process */
        pause();
        return 0;
    }

    /* Switch back to original process group.  Child remains in the new one */
    if (setpgid(0, pgrp_orig))
        perror("setpgid");

    printf("Parent pid=%ld, pgid=%ld\n", (long)getpid(), (long)getpgrp());
    printf("Child pid=%ld, pgid=%ld\n", (long)child, (long)getpgid(child));

    /* Wake child up to finish up */
    kill(child, SIGUSR1);
    wait(&status);

    return 0;
}

请注意,如果父进程在子进程退出之前尝试在setsid()这里调用,则会触发您询问的失败情况。

但是,由于对可能导致的允许转换的限制setpgid(),这不会导致您担心的那种随机故障。破损仅限于单个会话。

于 2011-07-22T04:36:37.130 回答