Немо верно, что 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()
, это не может вызвать случайные сбои, о которых вы беспокоитесь. Поломка ограничивается одним сеансом.