假设pid X
是进程组负责人并且X
终止,但进程组中的其他进程仍在运行(X
为其pgid)。 Linux是否会阻止将值X
指定为新进程的pid?
我问这是因为失败条件POSIX允许setsid
:
[EPERM]调用流程已经是流程组负责人,或调用流程以外的流程的流程组ID与调用流程的流程ID匹配。
对于使用将“随机”触发的进程组(即shell)的代码,此错误似乎是一个不可恢复的条件,使其更加可恶。我认为任何旨在达到理智水平的实现都会避免将X
重新分配为pid,同时它仍在作为pgid使用,但我无法在任何地方找到它。
答案 0 :(得分:6)
答案 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()
可能导致的允许转换限制,这不会导致您担心的随机故障。破损仅限于一次会议。