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

时间:2015-02-21 20:13:07

标签: 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;
}

2 个答案:

答案 0 :(得分:37)

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

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

答案 1 :(得分:18)

在你调用fork的时候,两个进程都有字符串&#34; Test&#34;在他们的标准输出缓冲区中。当每个进程退出时,它们都会将此文本刷新到输出(有关说明,请参阅exit)。你可以(按照建议)在缓冲区中添加换行符(由于缓冲,它会碰巧出现 - 请参阅setbuf进行解释)。或者你可以在前叉之前调用fflush(stdout)并获得你所要求的 - &#34;测试&#34;字符串。