fork() 系统调用异常执行

问题描述 投票:0回答:1

我只是在学习如何在 C 中使用 fork(),但我很难理解执行流程。

代码:

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

int main() {
    printf("starting...\n");

    int x = 100;

    int rc = fork();

    if (rc < 0) {
        printf("unable to fork\n");
        exit(-1);
    } else if (rc == 0) {
        x = x + 200;
        printf("child x == %d\n", x);
    } else {
        x = x + 500;
        printf("parent x == %d\n", x);
    }
    return 0;
}

如您所想的那样执行:

user@fedora> ./main
starting...
parent x == 600
child x == 300

当我移除时发生了奇怪的事情 来自

printf("starting...\n");
:

user@fedora> ./main
starting...parent x == 600
starting...child x == 300

为什么当我删除

\n
“开始...”打印两次,而它显然不应该?

请你解释一下为什么在这种情况下

printf("starting...")
被执行了两次?

谢谢!

c linux fork
1个回答
0
投票

您的问题不在于 fork 系统调用;相反,它与 C 的公共 I/O 操作的缓冲方式有关。

在 C 中,

printf()
函数并不总是输出到终端。相反,它写入一个缓冲区,当缓冲区被刷新时,终端实际上被写入了。这通常发生在换行符 ' ' 被打印出来,缓冲区已满,或者缓冲区被手动刷新
fflush(stdout)
.

当从初始 printf() 语句中删除 n 时,“starting...”字符串将写入代码中的缓冲区,但不会立即刷新到终端。

整个过程,包括未刷新的缓冲区,然后在创建 fork() 函数时被复制。 这表明“starting...”现在出现在父进程和子进程的输出缓冲区中。

终止进程的任何未刷新输出都会自动刷新。为此,对于每个过程,“starting...”被打印两次。

在初始

printf()
指令中保留 n 或在调用 fork() 之前手动刷新缓冲区是解决此问题的两种方法:

printf("starting...");
fflush(stdout);
© www.soinside.com 2019 - 2024. All rights reserved.