此代码中 Linux 上的 fork() 系统调用的行为

The behavior of the fork() system call on Linux in this code

我在书籍和在线资源中了解到,fork() 系统调用会创建当前进程的副本,并且两个进程都从执行 fork() 系统调用后的那一刻开始执行。正确吗?

如果它是正确的那么为什么下面的代码打印 "Test Test"?它应该只打印一次 "Test"(由父进程)。

#include <sys/types.h> /* pid_t */
#include <sys/wait.h>  /* waitpid */
#include <stdio.h>     /* printf, perror */
#include <stdlib.h>    /* exit */
#include <unistd.h>    /* _exit, fork */


int main(void)
{
    int ctr =1;
    int pc = 1;
    printf("%s", "Test ");
    pid_t pidmain = fork();
    return EXIT_SUCCESS;
}

当您调用 fork() 时,操作系统会创建当前进程整个内存的副本(它实际上并不复制内存,因为它可以使用 MMU 有效地执行此操作)。

由于 stdout 默认情况下是缓冲的,因此它只会在写入换行符或刷新流后才打印消息。当您 fork 一个新进程时,当前写入缓冲区(包含 "Test ")也将在新进程中复制。一旦进程退出,这将被打印出来,因为它隐式关闭(并刷新)stdout。 如果将 printf("%s", "Test "); 替换为 printf("%s\n", "Test "); 或在 fork() 之前添加 fflush(stdout); 调用,您将看到预期的输出。

在调用 fork 时,两个进程的标准输出缓冲区中都有字符串 "Test "。当每个进程退出时,它们都会将此文本刷新到输出(请参阅 exit for explanation). You could (as suggested) add a newline to the buffer (and it would happen to come out because of the buffering -- see setbuf 了解解释)。或者你可以在 fork 之前调用 fflush(stdout) 并得到你所要求的 - "Test " 字符串。