关于 Unix 中系统函数实现的困惑 [英] Confusion about a implementation of the system function in Unix

查看:27
本文介绍了关于 Unix 中系统函数实现的困惑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

来自 APUE 的 Unix system 函数的实现:

A implementation of the Unix system function from APUE:

图 8.22 system 函数,无信号处理

Figure 8.22 The system function, without signal handling

#include    <sys/wait.h>
#include    <errno.h>
#include    <unistd.h>

int
system(const char *cmdstring)   /* version without signal handling */
{
    pid_t   pid;
    int     status;

    if (cmdstring == NULL)
        return(1);      /* always a command processor with UNIX */

    if ((pid = fork()) < 0) {
        status = -1;    /* probably out of processes */
    } else if (pid == 0) {              /* child */
        execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);
        _exit(127);     /* execl error */
    } else {                            /* parent */
        while (waitpid(pid, &status, 0) < 0) {
            if (errno != EINTR) {
                status = -1; /* error other than EINTR from waitpid() */
                break;
            }
        }

        // if(waitpid(pid, &status, 0) < 0){
        //     if(errno != EINTR){
        //         status = -1;
        //     }
        // } 
    }

    return(status);
}

为什么它对 waitpid 使用 while 循环而不是我在注释中添加的 if 语句?我尝试了 if 并且到目前为止没有任何错误.

Why does it use a while loop for waitpid instead of a if statement that I add in the comments? I tried with if and did not get anything wrong so far.

推荐答案

除了子进程结束之外,waitpid 函数在被信号中断时可以提前返回.如果发生这种情况,将不会进入 if 块,并且将再次尝试 waitpid.

Besides the child process ending, the waitpid function could return early if it was interrupted by a signal. If that happens to be the case, the if block won't be entered and waitpid will be attempted again.

在没有循环的情况下,如果 waitpid 被中断,您最终会处于父进程不等待子进程的状态,并且当子进程退出时,您最终会遇到僵尸进程.在父进程退出之前,不会清除僵尸进程,此时 init 进程成为父进程并自动等待僵尸进程.

Without the loop, if waitpid gets interrupted you end up in a state where the parent process doesn't wait for the child and you end up with a zombie process when the child does exit. That zombie won't be cleaned up until the parent process exits, at which point the init process becomes the parent and automatically waits for the zombies.

这篇关于关于 Unix 中系统函数实现的困惑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆