样本1.1

样本1.1

当使用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./
$

相关内容