【问题标题】:Can someone please explain how this works?fork(),sleep()有人可以解释一下这是如何工作的吗?fork(),sleep()
【发布时间】:2017-03-06 13:53:58
【问题描述】:
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
#include<stdlib.h>

int main(void)

{
  pid_t pids[10];
  int i;

for (i = 9; i >= 0; --i) {
    pids[i] = fork();
    if (pids[i] == 0) {
        printf("Child%d\n",i);
        sleep(i+1);
        _exit(0);
    }
}

for (i = 9; i >= 0; --i){
    printf("parent%d\n",i);
    waitpid(pids[i], NULL, 0);
    }
return 0;
}

这里发生了什么? sleep() 如何在 for 循环中执行?什么时候被调用?这是输出:

parent9
Child3
Child4
Child2
Child5
Child1
Child6
Child0
Child7
Child8
Child9  //there is a pause here
parent8
parent7
parent6
parent5
parent4
parent3
parent2
parent1
parent0

请解释这个输出。我无法理解它是如何工作的。 一步一步的分析会很棒。

【问题讨论】:

    标签: linux fork wait zombie-process


    【解决方案1】:

    在第一个循环中,原始(父)进程创建了 10 个自身的副本。这些子进程中的每一个(通过fork() 返回零的事实检测到)打印一条消息,休眠并退出。所有的孩子基本上是同时创建的(因为父母在循环中做的很少),所以当他们每个人第一次被安排时有点随机 - 因此他们的消息的顺序是混乱的。

    在循环期间,将构建一个子进程 ID 数组。在所有 11 个进程中都有一个 pids[] 数组的副本,但只有在父进程中它是完整的 - 每个子进程中的副本将缺少编号较小的子 PID,并且其自己的 PID 为零。 (这并不重要,因为只有父进程实际使用该数组。)

    第二个循环只在父进程中执行(因为在此之前所有子进程都已退出),并等待每个子进程退出。它等待第一个睡了 10 秒的孩子;所有其他消息早已退出,因此所有消息(第一条除外)都快速连续出现。这里不可能随机排序,因为它是由单个进程中的循环驱动的。请注意,第一个父消息实际上出现在任何子消息之前 - 在任何子进程能够启动之前,父能够继续进入第二个循环。这又只是进程调度程序的随机行为——“parent9”消息可能出现在“parent8”之前的序列中的任何位置。

    我看到你用“僵尸进程”标记了这个问题。 Child0 到 Child8 在此状态下花费一秒或更多秒,在他们退出的时间和父母对他们执行waitpid() 的时间之间。在 Child9 退出之前,父进程已经在等待它,因此一个进程基本上没有时间成为僵尸。

    如果每个循环中有两条消息 - 一条在sleep/waitpid 之前和一条之后,则此示例代码可能会更清楚一些。颠倒第二个循环的顺序(或等效地,将第一个循环更改为sleep(10-i))也是有益的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-12
      • 1970-01-01
      • 2023-01-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多