我正在关注fork()
关于printf("before ");
fork();
printf("after ");
,但有些事情对我来说并不清楚。
两个进程将在fork()调用之后的下一个语句处开始执行。在这种情况下,两个进程将在赋值语句中开始执行,如下所示:
根据这句话,这个脚本
printf("after")
应该打印:(因为子进程将从before after after
开始)
before after before after
但它正在打印这个:
{{1}}
子进程是从文件的第一行开始的吗?你能告诉我我的代码有什么问题吗?我误解了那句话吗?
修改
在OS X上编译和执行的脚本
答案 0 :(得分:7)
当您创建新流程时,它会继承'原始过程的所有变量 - 因此也是所有缓冲区。自"之前"还没有刷新并且仍然在缓冲区中,子进程也将在缓冲区中包含此字符串并打印它。因此,您必须在分支过程之前调用fflush(stdout);
。
答案 1 :(得分:3)
你正确地理解了这句话,但是......
当您致电fork
时,它会获取流程的快照,并创建完全相同的副本。因此,如果stdout
中有缓冲的数据等待写入控制台,那么该数据将在fork之后的子输出缓冲区以及父缓冲区中。
有两种方法可以在fork之前清除输出缓冲区。您可以在\n
printf
printf( "before\n" );
fork();
printf( "after\n" );
或者您可以使用fflush
功能
printf( "before " );
fflush( stdout );
fork();
printf( "after " );
答案 2 :(得分:2)
这是因为"之前"缓冲并仅在刷新缓冲区时输出。这发生在两个进程终止时。
答案 3 :(得分:1)
如果您在fflush
之前的stdout
上致电fork
,您会看到预期的输出。一般来说,当你在操作系统级别进行操作时,C缓冲IO不会很好地发挥作用。
与标准输出关联的内存缓冲区克隆在fork
上,包括任何先前缓冲的输出。这就是为什么你看到"之前"两次。