关于 Unix 中系统函数实现的困惑 [英] Confusion about a implementation of the system function in 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屋!