代码之家  ›  专栏  ›  技术社区  ›  Kyle Brandt

等待进程组时,waitpid()中没有子进程错误

  •  6
  • Kyle Brandt  · 技术社区  · 15 年前

    写自己的玩具外壳,并遇到了一个尝试实现工作控制的碰撞。

    我正在用setpgid设置子进程组,包括子进程组和父进程组。我的等待电话是:

    pid = waitpid(-pid, &status, 0)
    

    然而,waitpid返回-1,perror说“没有子进程”。然而,它似乎每次都在等待。另外,从shell运行时,ps输出的含义似乎是正确的。因为ps父进程和我预期的一样是kbsh。

    % ps -o pid,ppid,pgrp,session,tpgid,comm
    Forking
    In Parent: Setting process group to 20809 of process 20809 with setpgid
    In Child Processes, pid of child process is 20809
    in Child: Setting process group to 20809 of process 20809 with setpgid
    Requesting that Process Group 20809 becomes the foreground process with tcsetpgrp
    Waiting for job with process group 20809
      PID  PPID  PGRP  SESS TPGID COMMAND
    12002 32573 12002 12002 20809 zsh
    20808 12002 20808 12002 20809 kbsh
    20809 20808 20809 12002 20809 ps
    Wait Error: No child processes
    Restoring Shell process group 20808 to forground
    

    有人看到我做错了什么吗?如果需要,可以发布更多代码…

    3 回复  |  直到 15 年前
        1
  •  13
  •   Kyle Brandt    15 年前

    我忽略了Sigchld,来自Waitpid的主页:

    posix.1-2001指定如果 处置 Sigchld设置为 sig ou ign或sa ou nocldwait标志是 设置为sigchld(请参见sigaction(2)), 那么终止的孩子就不会 变成僵尸并调用wait()或 waitpid()将阻止,直到全部 孩子们已经结束了,然后 失败,errno设置为echild。 (The 原始posix标准左 将SIGCHLD设置为的行为 未指定sig-ign。)Linux 2.6 符合本规范。 然而,Linux2.4(及更早版本)确实做到了 不是:如果wait()或waitpid()调用是 在忽略sigchld时生成, 呼叫的行为就像 Sigchld没有被忽视 是的,呼叫会一直挂到下一个 子级终止,然后返回 进程ID和该子进程的状态。

        2
  •  2
  •   eyalm    15 年前

    您不必设置进程组ID。默认情况下,子进程将父进程组的PID继承为组。 等待时,需要等待父级的PID:

    int main(int argc, char **argv)
    {
        pid_t pid;
        int stat;
    
        if ((pid = fork()))
        {
            printf("PARENT: %d | CHILD: %d\n", getpid(), pid);
            waitpid(-getpid(), &stat, 0);
            printf("DONE: %m\n");
        }
        else
        {
            printf("CHILD: %d\n", getpid());
            sleep(3);
        }
        return 0;
    }
    
        3
  •  2
  •   pjgranahan    10 年前

    我在尝试为我的计算机科学课程实现一个小的外壳时发现了这个线程,我想我会分享为我工作的东西。我收到以下错误:

    Waitpid error: No child processes
    

    在我的例子中,我使用的是计算机系统提供的包装器: 一本程序员的透视教科书。为了纠正我的错误,我改变了 Waitpid 在里面 csapp.c

    pid_t Waitpid(pid_t pid, int *iptr, int options) 
    {
        pid_t retpid;
    
        if ((retpid  = waitpid(pid, iptr, options)) < 0) 
            unix_error("Waitpid error");
        return(retpid);
    }
    

    pid_t Waitpid(pid_t pid, int *iptr, int options)
    {
            pid_t retpid;
    
            retpid  = waitpid(pid, iptr, options);
            if (retpid < 0 && errno != ECHILD)
                    unix_error("Waitpid error");
            return(retpid);
    }