Fork()新进程并写入子进程和父进程的文件
问题描述:
我是fork(),父进程和子进程的新手,并且难以理解我编写的代码背后的逻辑,但是没有执行I预期。以下是我有:Fork()新进程并写入子进程和父进程的文件
int main (int argc, char** argv)
{
FILE *fp_parent;
FILE *fp_child;
fp_parent = fopen ("parent.out","w");
fp_child = fopen ("child.out","w");
int test_pid;
printf ("GET HERE\n");
fprintf (fp_parent,"Begin\n"); // MY CONCERN
for (int i = 0; i < 1; i++) //for simplicity, just fork 1 process.
{ // but i want to fork more processes later
test_pid = fork();
if(test_pid < 0)
{
printf ("ERROR fork\n");
exit (0);
}
else if(test_pid == 0) // CHILD
{
fprintf(fp_child,"child\n");
break;
}
else //PARENT
{
fprintf(fp_parent,"parent\n");
}
}
fclose(fp_parent);
fclose(fp_child);
}
所以上面代码的输出是:
to stdout: GET HERE
in parent.out:
Begin
parent
Begin
in child.out:
child
我主要担心的是,我不明白为什么“开始”被写入到parent.out两次。如果我完全删除了for循环,那么只有一个“开始”被写入预期。
所以我认为,这是因为fork(),肯定我想念或不理解它背后的一些逻辑。你能帮我解释一下吗?
我打算在parent.out的for循环之前写一些东西,并在parent.out的for循环中写一些东西。子进程将写入child.out。
答
在C中,使用FILE
结构的输入/输出操作在用户进程级别进行缓冲。在你的情况下,你写到fp_parent
的输出实际上没有写到磁盘上,并且在fork
时刻保存在本地缓冲区中。 fork
创建整个过程的副本,其中包含含有Begin
的缓冲区,这就是为什么它会在文件中出现两次。尝试在fork
之前放fflush(fp_parent);
。这将刷新缓冲区,脏行将从文件中消失。
fflush作品。但我试图在fprintf后插入同步,并得到相同的结果(加倍从parent.out开始)。为什么这不起作用? – 2014-10-11 09:13:55
并且你可以指定这个缓冲区位于内核空间的位置吗? – 2014-10-11 09:15:58
这与内核没有任何关系。使用'FILE'的I/O在标准库中进行缓冲,该库与代码连接,并提供可执行程序。这意味着它与您自己的代码自己缓冲它在同一级别上发生。缓冲区由程序在您的程序地址空间中进行物理分配,这就是为什么它们被'fork'复制的原因。如果您不想使用这些缓冲区,请使用不带'f'的I/O函数,即“open”,“write”,“close”。 – Marian 2014-10-11 09:23:46