【问题标题】:Child process starts after parent process子进程在父进程之后启动
【发布时间】:2015-09-20 18:43:31
【问题描述】:

我有一个简单的代码来测试fork() 函数。

    #include<stdio.h>
    #include<unistd.h>
    #define MAX_COUNT 10
    void main(void)
    {
        pid_t pid;
        int i;
        fork();
        pid = getpid();
        for(i = 1; i <= MAX_COUNT; i++)
        {
            printf("PID = %d, i = %d\n", pid, i);
        }
    }

它没有像我预期的那样工作。

我的期望是:父母的结果和孩子的结果交替出现。 有人可以解释一下并教我如何解决吗?谢谢!

    PID = 3663, i = 1
    PID = 3663, i = 2
    PID = 3663, i = 3
    PID = 3663, i = 4
    PID = 3663, i = 5
    PID = 3663, i = 6
    PID = 3663, i = 7
    PID = 3663, i = 8
    PID = 3663, i = 9
    PID = 3663, i = 10
    PID = 3664, i = 1
    PID = 3664, i = 2
    PID = 3664, i = 3
    PID = 3664, i = 4
    PID = 3664, i = 5
    PID = 3664, i = 6
    PID = 3664, i = 7
    PID = 3664, i = 8
    PID = 3664, i = 9
    PID = 3664, i = 10

【问题讨论】:

  • 这两个进程独立运行,因此一旦发生分叉,您就不能期望任何特定的顺序(这取决于操作系统调度)。如果你想要一个特定的顺序,你必须自己使用同步机制明确地做到这一点。例如等待、信号量、互斥体、管道等。
  • 我的意思当然是在进程之间排序。流程中的排序自然而然地得到了很好的定义。
  • 尝试将 sleep(1); 添加到您的 for 循环中。
  • @QuestionC 这不是一个好主意。它将进程返回给调度程序,但不能保证调度程序会在进程之间交替。
  • 如果您的目标只是测试fork() 并四处逛逛,那么到处乱扔睡眠是很正常的做法。我相信 alternatingly 在这种情况下确实意味着非顺序。

标签: c linux fork


【解决方案1】:

主进程并没有立即放弃控制,而且 for 循环执行得如此之快,以至于它在第二个进程被调度之前就完成了。当我执行您的代码时,我会得到非连续打印,但行为取决于系统。

在玩fork() 时,有时抛出sleep() 命令会有所帮助。试试这个代码...

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

#define MAX_COUNT 10
int main(void)
{
  pid_t pid;
  int i;
  fork();

  pid = getpid();

  srand(pid); // Make sure each process has a different seed

  for(i = 1; i <= MAX_COUNT; i++)
  {
    printf("PID = %d, i = %d\n", pid, i);

    // Sleep 1-3 seconds.
    unsigned int sleep_seconds = rand() % 3 + 1;
    sleep(sleep_seconds);
  }
}

【讨论】:

    【解决方案2】:

    解释很简单。 进程的调度取决于内核。如果这是一个单核处理器,那么在这次运行中它决定暂停子进程并允许父进程首先运行。父级运行了几个循环,然后被暂停以支持子级,依此类推。
    在多处理器系统中,两个进程可以串联运行,但控制台设备将根据中断时间交替输出。

    无法保证不同的运行会产生相同的输出。也不能保证不同的内核版本不会做其他事情。

    如果您希望进程在循环之间交替,现在是学习interprocess communication 的时候了。

    【讨论】:

    • 一般来说,您可以期望内核在调度进程时是“公平的”。这意味着,如果父进程和子进程运行很长时间,它们将获得大致相同的处理时间,并且在两次激活之间都不必等待太长时间。当然,这里考虑的时间尺度远远大于几个循环迭代。
    猜你喜欢
    • 1970-01-01
    • 2014-06-25
    • 2011-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多