首页 文章

为什么在父级中fork()然后wait()?

提问于
浏览
2

我知道fork(),wait(),waitpid(),zombie进程......我通过阅读W. Richard Stevens来理解它们,这是一本非常好的书 .

如果我们不在父母中调用wait(),孩子在终止后变成僵尸......这很糟糕!

如果我们在父级中调用wait(),则父级等待子级终止,接收终止状态然后继续 . 写?

我已经经历了许多调用fork()一次然后在父类中调用wait()的示例 .

但是,如果所有的父母都要等孩子并在孩子终止后继续,那么就没有实际的多任务处理(技术上是的,有2个进程 . 但从逻辑上讲没有用)那么为什么我们在这里调用fork()?

我们可以编写子代码,然后编写父代码,而不是fork()&wait()作为单个进程...不是更好吗?

谢谢!

2 回答

  • 0

    有时,即使父母立即阻止,它也很有用 fork() . 最常见的情况是当您执行类似于 system() 调用的操作,执行外部命令并等待它完成时:您将执行 fork() execve() . (但是,在现代代码中,您应该考虑使用 posix_spawn() 来实现此目的 . )

    尽管如此, wait() 不需要阻止 . 您可以使用带有标志 WNOHANGwaitpid() 来收集任何已完成进程的退出代码,或者如果它仍在运行则立即继续 .

  • 1

    您在 fork()waitpid() 之间编写的代码与子fork同时运行 .

    父母一直等到孩子完成,通常只是为了获取从孩子那里传递的数据,然后将其暴露给父母 . 假设您运行一个主循环,其中任务作为“背景”运行 . 例如:

    // a simple scheduler
    while(1) {
       if(done_task_1) {
          // if done_task_1 is ever to change in the parent memory scope,
          // parent must know the exit status of its child fork.
          // otherwise there is no way to enter this if sentance, ever
          collect_data_1();
          run_task_1 = 0;
       }
       else if(run_task_1 == 1) {
          // iterate instructions for a sec
          posix_kill(pid_task_1, SIGCONT);
          sleep(1);
          posix_kill(pid_task_1, SIGSTOP);
    
       } 
    
       if(done_task_2) {
          collect_data_2();
          run_task_2 = 0;
       }
       else if(run_task_2 == 1) {
          // iterate instructions for a sec
          posix_kill(pid_task_2, SIGCONT);
          sleep(1);
          posix_kill(pid_task_2, SIGSTOP);
    
       } 
       if(run_task_1 == 0 && run_task_2 == 0) {
           break;
       }
    }
    

相关问题