为什么我们要在等待后检查 WIFEXITED 以杀死 Linux 系统调用中的子进程?

Yos*_*Yos 6 c unix linux operating-system

我在 C 中遇到了一些代码,我们在其中检查了 的返回值,wait如果它不是错误,则还有另一个检查WIFEXITEDand WIFEXITSTATUS。为什么这不是多余的?据我了解,wait如果发生错误则返回 -1,而WIFEXITED如果wait子进程正常终止则返回非零值。因此,如果此行中没有任何错误,if ( wait(&status) < 0 )为什么在WIFEXITED检查期间会出错?

这是代码:

#include <stdio.h>
#include <signal.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>

#define CHILDREN_NUM 5

int main () {

    int i, status, pid, p;
    for(i = 0; (( pid = fork() ) < 0) && i < CHILDREN_NUM;i++)
        sleep(5);


    if ( pid == 0 )
    {
        printf(" Child %d : successfully created!\n",i);
        exit( 0 );  /* Son normally exits here! */
    }

    p = CHILDREN_NUM;
    /* The father waits for agents to return succesfully */
    while ( p >= 1 )
    {
        if ( wait(&status) < 0 ) {
            perror("Error");
            exit(1);
        }

        if ( ! (WIFEXITED(status) && (WEXITSTATUS(status) == 0)) )  /* kill all running agents */
        {
            fprintf( stderr,"Child failed. Killing all running children.\n");
           //some code to kill children here
            exit(1);
        }
        p--;
    }

    return(0);
}
Run Code Online (Sandbox Code Playgroud)

Tho*_*zco 7

wait返回>= 0告诉您子进程已终止(并且该调用wait没有失败),但它不会告诉您该进程是否成功终止(或是否已发出信号)。

但是,在这里,查看您的代码,很明显程序确实关心终止的子进程是否成功:

fprintf( stderr,"Child failed. Killing all running children.\n");

因此,程序需要对statuswait以下内容填充的结构进行进一步测试:

  • WIFEXITED(status): 进程是否正常退出?(而不是发出信号)。
  • WEXITSTATUS(status) == 0:进程是否以退出代码 0 退出(又名“成功”)。有关详细信息,请参阅:linux 命令返回的退出状态 1 的含义


PSk*_*cik 5

wait(&status)等待子进程的终止。终止可能是由于自愿退出或由于收到未处理的信号(其默认处理是终止进程)而导致。

WIFEXITED(status)WIFSIGNALED(status)允许您区分这两种*情况,并且稍后可以使用 或WEXITSTATUSWTERMSIG检索退出状态 ( if(WIFEXITED(status)) 或终止信号 ( if(WIFSIGNALED(status))。


*使用waitpid和 特殊标志 ( WUNTRACED, WCONTINUED),您还可以等待子进程停止和恢复,您可以分别使用WIFSTOPPEDWIFCONTINUED(仅限 Linux)进行检测。有关详细信息,请参阅waitpid(2) 。