Waitpid和fork / exec在系统调用方面的非阻塞优势?

时间:2017-03-16 17:28:38

标签: c linux unix fork waitpid

我总是听说你永远不应该使用system()而不是fork/exec,因为system()会阻止父进程。

如果是这样,我是否通过调用waitpid()做错了什么,当我执行fork/exec时,它也会阻止父进程?有没有办法调用waitpid ......我一直认为在做fork/exec时是必要的。

pid_t pid = fork();

if (pid == -1)
{
    // failed to fork
} 
else if (pid > 0)
{
    int status;
    waitpid(pid, &status, 0);
}
else 
{
    execve(...);
}

3 个答案:

答案 0 :(得分:2)

WNOHANG标志(在options参数中设置)将调用waitpid()非阻塞。

你必须定期打电话来检查孩子是否已经完成。

或者您可以设置SIGCHLD来照顾孩子。

答案 1 :(得分:2)

如果您想要在子进程关闭的情况下执行其他操作,则可以为SIGCHLD设置一个处理子项完成/退出的陷阱。就像在这个非常简单的例子中一样。

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

pid_t pid;
int finished=0;

void zombie_hunter(int sig)
    {
    int status;
    waitpid(pid, &status, 0);
    printf("Got status %d from child\n",status);
    finished=1;
    }

int main(void)
    {
    signal(SIGCHLD,zombie_hunter);

    pid = fork();

    if (pid == -1)
        {
        exit(1);
        } 
    else if (pid == 0)
        {
        sleep(10);
        exit(0);
        }

    while(!finished)
        {
        printf("waiting...\n");
        sleep(1);
        }
    }

答案 2 :(得分:1)

  

我总是听说你永远不应该使用system()而不是fork/exec,因为system()会阻止父进程。

永远不要说永远。如果system()具有您想要的语义,包括但不限于阻止调用进程,那么一定要使用它!但请确保您理解所有那些语义。

如果你的目标是避免阻止父进程,那么重要的是要理解父进程可以在分叉子代之间执行无限量的工作,并通过wait()函数族之一来收集它。这非常类似于启动一个新线程,继续其他工作,然后最终加入该线程。

此外,如果父母在孩子终止时不需要知道或关心,那么就可以避免任何等待它的需要。