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()
,这不会导致您担心的那种随机故障。破损仅限于单个会话。