2014-10-11 56 views
3

我是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。

回答

4

在C中,使用FILE结构的输入/输出操作在用户进程级别进行缓冲。在你的情况下,你写到fp_parent的输出实际上没有写到磁盘上,并且在fork时刻保存在本地缓冲区中。 fork创建整个过程的副本,其中包含含有Begin的缓冲区,这就是为什么它会在文件中出现两次。尝试在fork之前放fflush(fp_parent);。这将刷新缓冲区,脏行将从文件中消失。

+0

fflush作品。但我试图在fprintf后插入同步,并得到相同的结果(加倍从parent.out开始)。为什么这不起作用? – 2014-10-11 09:13:55

+0

并且你可以指定这个缓冲区位于内核空间的位置吗? – 2014-10-11 09:15:58

+1

这与内核没有任何关系。使用'FILE'的I/O在标准库中进行缓冲,该库与代码连接,并提供可执行程序。这意味着它与您自己的代码自己缓冲它在同一级别上发生。缓冲区由程序在您的程序地址空间中进行物理分配,这就是为什么它们被'fork'复制的原因。如果您不想使用这些缓冲区,请使用不带'f'的I/O函数,即“open”,“write”,“close”。 – Marian 2014-10-11 09:23:46