Waitpid 和 fork/exec 相对于系统调用的非阻塞优势?

Waitpid and fork/exec's non-blocking advantage over a syscall?

我总是听说你永远不应该使用 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(...);
}

WNOHANG 标志(在选项参数中设置)将调用 waitpid() non-blocking。

您必须定期调用它以检查 child 是否已完成。

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

I always hear that you should never use system() and instead fork/exec because system() blocks the parent process.

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

如果您的 objective 是为了避免阻塞 parent 进程,那么了解 parent 可以在分叉 [=24] 之间执行无限量的工作很重要=] 并通过 wait() 函数族之一收集它。这非常类似于启动一个新线程,继续其他工作,然后最终加入线程。

此外,如果 parent 不需要知道或关心 child 何时终止,那么就可以完全避免等待它。

如果您想在子进程关闭时做其他事情,您可以为处理子进程的 SIGCHLD 设置一个陷阱 finishing/exiting。就像这个非常简单的例子。

#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);
        }
    }