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

Aka*_*jan 27 c linux fork

我已阅读书籍和在线资源,fork()系统调用创建当前进程的副本,并且两个进程从fork()系统调用之后的点开始执行.这是对的吗?

如果它是正确的,为什么下面的代码打印"测试测试"?它应该只打印一次"测试"(通过父进程).

#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;
}
Run Code Online (Sandbox Code Playgroud)

ar3*_*r31 37

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

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

  • 或者如果C库决定缓冲区中开始出现太多...依赖于缓冲区中剩余的输出并在fork调用期间被复制将是错误的. (6认同)

Tho*_*key 18

在您调用fork的位置,两个进程在其缓冲区中都有标记输出的字符串"Test".当每个进程退出时,它们都会将此文本刷新到输出(请参阅exit以获取解释).您可以(如建议的那样)向缓冲区添加换行符(由于缓冲,它会发生 - 请参阅setbuf以获得解释).或者你可以在fork之前调用fflush(stdout)并获得你所要求的 - "Test"字符串.