【问题标题】:Why this code does not print two "hello" when using multi process?为什么在使用多进程时这段代码不打印两个“hello”?
【发布时间】:2020-02-19 14:43:51
【问题描述】:

我正在学习多进程,知道使用fork()创建子进程时,子进程获取父进程栈、数据、堆和文本段的副本。

那么为什么下面这段代码不打印两个“hello”呢?

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>

static int idata = 111; /* Allocated in data segment */

int main(int argc, char *argv[])
{

    int istack = 222; /* Allocated in stack segment */
    pid_t childPid;
    idata *= 2;
    istack *= 2;
    printf("hello\n");

    switch (childPid = fork()) {
            case -1:
                    printf("fork fail\n");
                    exit(0);
            case 0:
                    idata *= 3;
                    istack *= 3;
                    break;
            default:
                    sleep(3); // Give child a chance to execute
                    break;
    }
    /* Both parent and child come here */

    printf("PID=%ld %s idata=%d istack=%d\n", (long) getpid(),
    (childPid == 0) ? "(child) " : "(parent)", idata, istack);

    exit(0);
}

结果是

你好

PID=591(子)idata=666 istack=1332

PID=590(父)idata=222 istack=444

为什么这段代码不打印两个“hello”?

【问题讨论】:

  • 子进程从调用fork的行开始执行
  • 程序打印“hello”然后分叉。父母和孩子都不会重置为较早的代码;他们都从分叉继续。

标签: c linux process multiprocessing


【解决方案1】:

跟踪程序流程。首先只有一个进程执行这个程序。这个过程打印“你好”。接下来,在 switch 语句内部有一个 fork 系统调用。现在有两个进程,父进程和子进程。孩子是父母的克隆。除进程 ID 外,其他所有内容对两者都是相同的。甚至下一条要执行的指令对两者都是相同的。接下来,父母和孩子都执行 switch 语句。孩子从来没有机会打印“你好”。

【讨论】:

    【解决方案2】:

    printf("hello\n"); 发生在 fork() 之前。

    当输出为终端时,stdout 默认为行缓冲,它输出 1 hello 因为stdout\n 上被刷新。

    当输出被重定向到文件或管道时,stdout 默认是块缓冲的,它输出 2 个hellos,因为父进程和子进程都有 hello 缓冲并且缓冲区被刷新exit().

    【讨论】:

    • 感谢您的回答,但我有一个困惑。为什么 istack *= 2 发生在 fork() 之前,但子进程仍然执行此代码?
    • @T1412 我无法理解你的问题,抱歉。
    • 我的意思是子进程还在执行istack*2
    • @T1412 子进程在fork 语句之后开始,它得到istack 的副本,其值与fork 之前的值无关。
    【解决方案3】:

    在调用 fork() 函数之前,您正在创建 printf("hello\n");

    【讨论】:

      猜你喜欢
      • 2018-10-31
      • 1970-01-01
      • 1970-01-01
      • 2017-12-16
      • 2017-10-14
      • 2012-03-23
      • 1970-01-01
      • 2023-03-25
      • 1970-01-01
      相关资源
      最近更新 更多