C 子进程的setpgid:没有这样的进程

C 子进程的setpgid:没有这样的进程,c,unix,operating-system,C,Unix,Operating System,我不知道为什么我的电脑会出现这样的错误。我已经在其他一些计算机上测试了代码。它工作得很好 如果我删除睡眠(2),它就会工作。我想我应该能够为僵尸进程设置PGID。它是否依赖于操作系统的实现 #include <unistd.h> #include <stdlib.h> #include <stdio.h> #define CHECK(syscall, msg) do { \ if ((syscall) == -1

我不知道为什么我的电脑会出现这样的错误。我已经在其他一些计算机上测试了代码。它工作得很好

如果我删除
睡眠(2)
,它就会工作。我想我应该能够为僵尸进程设置PGID。它是否依赖于操作系统的实现

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

#define CHECK(syscall, msg) do {                    \
    if ((syscall) == -1) {                          \
      perror(msg);                                  \
      _exit(1);                                     \
    }                                               \
  } while(0)

#define SAFE_CLOSE_NOT_STD(fd) do {                                 \
    if (fd != STDIN_FILENO && fd != STDOUT_FILENO && fd != -1) {    \
      CHECK(close(fd), "close error");                              \
      fd = -1;                                                      \
    }                                                               \
  } while(0)

int main () {
  int ls_pid;
  char *ls_argv[] = { "ls", NULL };

  CHECK(ls_pid = fork(), "fork error");
  if (!ls_pid) {
    CHECK(setpgid(0, 0), "child setpgid error");
    CHECK(execvp(ls_argv[0], ls_argv), "execve error");
  } else {
    printf("child pid:%d\n", ls_pid);
    sleep(2); // no error arises if I remove this line
    CHECK(setpgid(ls_pid, ls_pid), "setpgid error"); // error here
  }
  CHECK(wait(NULL), "wait error");

  printf("Finish\n");
}
#包括
#包括
#包括
#定义检查(syscall,msg)do{\
如果((系统调用)=-1){\
佩罗尔(味精)\
_出口(1)\
}                                               \
}而(0)
#定义安全关闭非标准(fd)do{\
如果(fd!=STDIN\u FILENO&&fd!=STDOUT\u FILENO&&fd!=-1){\
检查(关闭(fd),“关闭错误”)\
fd=-1\
}                                                               \
}而(0)
int main(){
int ls_pid;
char*ls_argv[]={“ls”,NULL};
检查(ls_pid=fork(),“fork error”);
如果(!ls_pid){
检查(setpgid(0,0),“子setpgid错误”);
检查(execvp(ls_argv[0],ls_argv),“execve error”);
}否则{
printf(“子pid:%d\n”,ls\u pid);
sleep(2);//如果删除此行,则不会出现错误
检查(setpgid(ls_-pid,ls_-pid),“setpgid错误”);//此处有错误
}
检查(等待(空),“等待错误”);
printf(“Finish\n”);
}

由于子进程已退出且不再存在,因此睡眠时会出现错误。当执行僵尸进程的父进程切换到子进程,子进程中的执行进程用新进程替换当前进程并退出时,你不能对僵尸进程执行任何操作,除非调用
等待

。当它在
2秒后返回到父进程时
子进程不存在,这就是
setpgid
失败的原因

CHECK(setpgid(ls_pid, ls_pid), "setpgid error");
setpgid
的手册页可以看到,这是一个
EACCES
错误

试图更改的进程组ID 调用进程和 孩子已经执行了一个execve(2)(setpgid()
setpgrp())。

假设我在子进程退出之前更改了它的PGID。现在,子进程和父进程具有不同的PGID。哪一个是前台组?在任何时候,会话中只有一个进程组可以是终端的前台进程组;其余的进程组位于后台。