当使用wait
函数时,执行示例 1.1 时SIGCHLD
会消耗信号wait
,如下所示。
样本1.1
if (pid==0){
printf("child\n");
printf("%d\n",pid);
}
else{
printf("Parent\n");
printf("%d\n",pid);
wait(NULL);
sleep (10);
}
如果我运行示例 1.2(如下),其中wait
省略了该函数,则子进程将失效。为什么wait
函数要处理SIGCHLD
信号?
示例1.2
if (pid==0){
printf("child\n");
printf("%d\n",pid);
}
else{
printf("Parent\n");
printf("%d\n",pid);
sleep (10);
}
答案1
虽然我们可以阅读您的 2 个样本,但您的问题几乎没有任何意义。
根据 POSIX / Single Unix 规范第 4 版 2018 版,当进程没有明确向系统表明它想要忽略其子进程的状态时:
应生成状态信息(退出状态代码等)。
[退出]进程应转变为僵尸进程。 ...
一旦其父进程获得进程的状态信息,该进程的生命周期将结束......
如果调用进程的父进程中的一个或多个线程在等待进程终止时调用 wait()、waitid() 或 waitpid() 时被阻塞,则其中一个(或者,如果有)正在使用 WNOWAIT 调用 waitid() ,可能更多)这些线程应获取[退出]进程的状态信息...并解除阻塞。
应将 SIGCHLD 发送至父进程。
请注意最后一点 -SIGCHLD
总是生成(除非父级指定忽略它)!
更新
我测试了你的两个程序片段,包装在一个我认为合理的存根中。两者都运行成功。这是2个完整的程序源代码和终端输出:
完整示例 1.1:
#include <stdio.h>
#include <sys/wait.h>
#include <unistd.h>
int main()
{
pid_t pid;
pid = fork();
if( pid == 0 ) {
printf("child\n");
printf("%d\n", pid);
}
else {
printf("Parent\n");
printf("%d\n", pid);
wait(NULL);
sleep(10);
}
}
完整示例 1.2:
#include <stdio.h>
#include <sys/wait.h>
#include <unistd.h>
int main()
{
pid_t pid;
pid = fork();
if( pid == 0 ) {
printf("child\n");
printf("%d\n", pid);
}
else {
printf("Parent\n");
printf("%d\n", pid);
sleep(10);
}
}
//64-bit Mac Mini./
$ make s1 s2 ; ./s1 ; ./s2
make: `s1' is up to date.
make: `s2' is up to date.
Parent
46431
child
0
Parent
46449
child
0
//64-bit Mac Mini./
$