【问题标题】:Understanding of Fork in C [duplicate]C语言中对Fork的理解[重复]
【发布时间】:2014-02-16 11:12:02
【问题描述】:

我对 fork 有一个我不明白的问题。

    #include <stdio.h>
    #include <string.h>

    main(){
      printf("test 1.\n"); 

      fork();

      printf("test 2.\n");  
    }

输出是:

测试 1.
测试 2.
测试 1.
测试2。

我不应该得到... :
测试1
测试2
测试2

我真的不明白这一点,因为 fork 应该在 fork(); 之后创建子进程;并且不再打印 teste1 。

【问题讨论】:

  • 如果在fork(); 之前添加fflush(stdout); 会发生什么?
  • 您缺少 unistd.h 标头。
  • 我在 ubuntu 机器上运行了相同的代码,并且得到了与您预期相同的输出。
  • 谢谢,fflush 成功了。如果我使用 write 而不是 printf 这也可以
  • 您的输出没有行缓冲?有趣...

标签: c


【解决方案1】:

当您调用printf 时,它不会立即打印任何文本。相反,它会一直等到您打印了大量文本,或者您调用fflush(stdout),或者程序退出。 (编辑:还有其他事情会导致打印缓冲文本)

当进程分叉时,它会复制未打印文本的缓冲区(其中包含“test 1.\n”)。两个进程退出时都会打印“test 1.\n”。

fork() 之前调用fflush(stdout) 可以解决此问题,方法是确保在进程分叉之前实际打印“test 1.\n”。

【讨论】:

    【解决方案2】:

    试试这个:

    void exit_message (void)
    {
       // use write to have an unbuffered output
       char m[100];
       sprintf (m, "%d exit\n", getpid());
       write (1, m, strlen(m));
    }
    
    main(){
      atexit (exit_message);
    
      printf("%d test 1\n",getpid()); 
    
      fork();
    
      printf("%d test 2\n",getpid());
      }
    

    输出将如下所示:

    14866 exit   // <- parent process flushes its output at exit
    14866 test 1 // <- parent process: 1st printf
    14866 test 2 // <- parent process: 2nd printf
    14867 exit   // <- forked process flushes its output at exit
    14866 test 1 // <- forked process: unflushed parent process output buffer
    14867 test 2 // <- forked process: 2nd printf
    

    我们可以看到分叉进程唯一完成的 printf 是最后一个,正如预期的那样。

    上一行是 stdout 输出缓冲区的影子,在刷新之前已被 fork() 复制。

    使标准输出无缓冲

    main(){
      atexit (exit_message);
      setvbuf(stdout, NULL, _IONBF, 0);
      printf("%d test 1\n",getpid()); 
    
      fork();
    
      printf("%d test 2\n",getpid());
    }
    

    赶走鬼

    14866 test 1 // <- parent process: 1st printf
    14866 test 2 // <- parent process: 2nd printf
    14866 exit   // <- parent process exits
    14867 test 2 // <- forked process: 2nd printf
    14867 exit   // <- forked process exits
    

    【讨论】:

    • 第一个示例中对setvbuf() 的调用应通过_IOFBF(“完全缓冲”)但_IONBF
    • @alk 好吧,我明白了。我忘了删除线。帖子已更新,谢谢。
    猜你喜欢
    • 1970-01-01
    • 2011-09-21
    • 2018-06-16
    • 1970-01-01
    • 1970-01-01
    • 2020-08-16
    • 2019-05-11
    • 1970-01-01
    • 2021-12-11
    相关资源
    最近更新 更多