C 奇怪的异常,写入文件时(写入标准输出时正常工作)
我对 C 很陌生,所以请耐心等待。我在这个问题上挣扎了很长时间,而且很难缩小错误原因的范围。
我注意到,当分叉进程并写入文件时(只有原始进程写入文件,会发生奇怪的事情,输出几乎乘以分叉数量,很难解释,因此我编写了一个小测试代码,您可以在其中运行并重新创建问题。
#include <stdio.h>
#include <stdlib.h>
void foo()
{
FILE* file = fopen("test", "w");
int i=3;
int pid;
while (i>0)
{
pid=fork();
if(pid==0)
{
printf("Child\n");
exit(0);
}
else if(pid > 0)
{
fputs("test\n", file);
i=i-1;
}
}
}
int main()
{
foo();
exit(EXIT_SUCCESS);
}
按原样编译并使用 file=stdout
运行一次。当写入 stdout
时,输出为
test test test
:文件的输出是:
test test test test test test
另外,如果您添加索引并将 i
更改为更大的数字,您可以看到某种模式,但这对我没有帮助,
坦率地说,我不知道为什么可以 。这种情况发生了,也不知道如何解决它,但我是 C 语言的新手,所以这一切可能只有一个正常的逻辑解释 =)。
感谢您的所有时间和答案。
I'm very new to C so please bear with me. I am struggling with this for really long time and I had a hard time to narrow down the cause of error.
I noticed that when forking process and writing to a file (only the original process writes to the file a strange thing happens, the output is nearly multiplied by the number of forks, hard to explain, thus I made a small test code where you can run and it recreates the problem.
#include <stdio.h>
#include <stdlib.h>
void foo()
{
FILE* file = fopen("test", "w");
int i=3;
int pid;
while (i>0)
{
pid=fork();
if(pid==0)
{
printf("Child\n");
exit(0);
}
else if(pid > 0)
{
fputs("test\n", file);
i=i-1;
}
}
}
int main()
{
foo();
exit(EXIT_SUCCESS);
}
Compile and run it once the way it is and once with file=stdout
. When writing to stdout
the output is:
test test test
But when writing to the file the output is:
test test test test test test
Also if you add indexing and change i
to a larger number you can see some kind of a pattern, but that doesn't help me.
Well frankly said I have no idea why could this happen, neither how to fix it. But I am a total novice at C so there might be just a normal logical explanation for all this =).
Thank you for all your time and answers.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
stdout
通常是无缓冲的或行缓冲的;其他文件通常是块缓冲的。您需要在fork()
之前使用fflush()
它们,否则每个子进程都会刷新自己的缓冲区副本,从而导致这种乘法。stdout
is usually unbuffered or line buffered; other files are typically block buffered. You need tofflush()
them beforefork()
, or every child will flush its own copy of the buffer, leading to this multiplication.