Linux是否允许将进程组ID重新分配给进程?

时间:2011-07-22 01:55:06

标签: c linux posix job-control process-group

假设pid X是进程组负责人并且X终止,但进程组中的其他进程仍在运行(X为其pgid)。 Linux是否会阻止将值X指定为新进程的pid?

我问这是因为失败条件POSIX允许setsid

  

[EPERM]调用流程已经是流程组负责人,或调用流程以外的流程的流程组ID与调用流程的流程ID匹配。

对于使用将“随机”触发的进程组(即shell)的代码,此错误似乎是一个不可恢复的条件,使其更加可恶。我认为任何旨在达到理智水平的实现都会避免将X重新分配为pid,同时它仍在作为pgid使用,但我无法在任何地方找到它。

2 个答案:

答案 0 :(得分:6)

没问题,因为fork guarantees

  

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

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

答案 1 :(得分: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()可能导致的允许转换限制,这不会导致您担心的随机故障。破损仅限于一次会议。