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

Kyl*_*ndt 7 c unix

编写我自己的玩具外壳,并试图实现作业控制.

我正在使用setpgid在子级和父级中设置子级的进程组.我的等待电话是:

pid = waitpid(-pid, &status, 0)
Run Code Online (Sandbox Code Playgroud)

但是,waitpid返回-1并且perror说"没有子进程".但是,它确实似乎每次都在等待.另外,ps输出在从shell运行时看起来正确.因为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
Run Code Online (Sandbox Code Playgroud)

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

Kyl*_*ndt 14

我在waitpid手册页中忽略了sigchld:

POSIX.1-2001指定如果SIGCHLD的处置设置为SIG_IGN或为SIGCHLD设置SA_NOCLDWAIT标志(请参阅sigaction(2)),则终止的子节点不会变为僵尸并且调用wait()或waitpid( )将阻止所有孩子终止,然后将errno设置为ECHILD失败.(原POSIX标准留给设置SIGCHLD为SIG_IGN不确定的行为.)的Linux 2.6符合本规范.但是,Linux 2.4(及更早版本)不会:如果在忽略SIGCHLD时进行wait()或waitpid()调用,则调用的行为就像SIGCHLD未被忽略一样,即调用阻塞直到下一个子句终止,然后返回该子进程的ID和状态.


pjg*_*han 6

我在尝试为我的计算机科学课程实现一个小 shell 时发现了这个线程,并认为我会分享对我有用的内容。我收到以下错误:

\n\n
Waitpid error: No child processes\n
Run Code Online (Sandbox Code Playgroud)\n\n

就我而言,我使用的是计算机系统提供的包装器:\nA Programmer\xe2\x80\x99s Perspective 教科书。为了修复我的错误,我改变Waitpidcsapp.c

\n\n
pid_t Waitpid(pid_t pid, int *iptr, int options) \n{\n    pid_t retpid;\n\n    if ((retpid  = waitpid(pid, iptr, options)) < 0) \n        unix_error("Waitpid error");\n    return(retpid);\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

\n\n
pid_t Waitpid(pid_t pid, int *iptr, int options)\n{\n        pid_t retpid;\n\n        retpid  = waitpid(pid, iptr, options);\n        if (retpid < 0 && errno != ECHILD)\n                unix_error("Waitpid error");\n        return(retpid);\n}\n
Run Code Online (Sandbox Code Playgroud)\n