【问题标题】:Why do we use wait when we create child processes?为什么我们在创建子进程时使用等待?
【发布时间】:2016-10-27 11:03:31
【问题描述】:

我是一名新的 C++ 程序员,我正在尝试弄清楚父进程和进程是如何工作的。为此,我尝试根据此处的代码创建三个进程。但是,我知道我们应该在每次创建子进程后退出以允许其他子进程,但我不明白在第二个 for 循环中,我们等待(NULL)三次。我们为什么要这样做呢?这是我第一次尝试了解父子进程。如果你也给我一个学习的资源,我会很高兴。谢谢!

int main(){

cout<<" Dad process is "<<getpid()<<endl;

for(int i=0;i<3;i++){
    if(fork()==0)
    {
        cout<<"Son pid "<<getpid()<<" from pid "<<getppid()<<endl;
        exit(0);
    }
}
for(int i=0;i<3;i++){
    wait(NULL);
}

}

`

【问题讨论】:

标签: c++ process fork parent multitasking


【解决方案1】:

如果不调用wait(),父进程将立即终止,而子进程可以继续运行。

对于像这里显示的那样一个简短的程序,这并不重要。

但是对于更大、更复杂的应用程序,子进程执行大量工作:让父进程终止会令人困惑。它给人的印象是刚刚执行的过程已经完成了它的工作。您回到了命令/shell 提示符,却没有立即意识到子进程仍在执行它们正在执行的任何操作。

此外,如果其中一个子进程遇到错误并以非零退出代码终止,则wait()ing 父进程可以收集退出代码,并以非零退出代码终止自身,表明进程失败。

【讨论】:

    【解决方案2】:

    当您调用 wait(NULL) 时,您是在要求操作系统等待任何子进程的“状态更改”。状态变化包括孩子从运行状态到退出状态。

    您可能应该改为调用 waitpid(childid),以便具体说明您正在等待的孩子。换句话说:

    int child_id = fork();
    if (child_id == 0)
    {
        /* do useful child work */
    }
    else
    {
        waitpid(child_id, ...);
    }
    

    为什么要等孩子?

    首先,您通常要求孩子们做有用的工作,并且您想知道他们什么时候完成。

    另一个原因是操作系统需要为该进程保留一些数据,即使它已经退出,直到你调用 wait()。因此,如果不调用 wait,您的孩子最终会成为“僵尸”进程(您会在 top 中看到它们)。

    您可以在这里看到一些典型的实际使用情况:
    https://github.com/deplinenoise/tundra/blob/master/src/ExecUnix.cpp#L102

    您可以在此处找到文档:
    https://linux.die.net/man/2/wait

    【讨论】:

      【解决方案3】:

      引用https://linux.die.net/man/2/wait

      ...用于等待调用进程的子进程的状态变化,并且 获取状态发生变化的孩子的信息。一个状态 变化被认为是:孩子终止了...

      还有一些其他的东西,但本质上这里的目的是等待子进程的终止。

      【讨论】: