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

R..*_*R.. 9 c linux posix job-control process-group

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

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

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

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

Nem*_*emo 6

没问题,因为fork保证:

子进程ID也不匹配任何活动进程组ID.

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


caf*_*caf 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;
}
Run Code Online (Sandbox Code Playgroud)

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

但是,由于setpgid()可能导致的允许转换的限制,这不会导致您担心的那种随机故障.破损仅限于一次会议.