【问题标题】:Fork() new process and write to files for child and parent processesFork() 新进程并写入子进程和父进程的文件
【发布时间】:2014-10-11 08:14:52
【问题描述】:

我是 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 循环,那么只会写入一个预期的“Begin”。

所以我认为这是因为 fork() 而我肯定错过或不理解它背后的一些逻辑。各位大神能帮我解释一下吗?

我的计划是能够在 parent.out 的 for 循环之前写一些东西,并在 parent.out 的 for 循环期间写一些东西。子进程将写入 child.out。

【问题讨论】:

    标签: c process fork file-descriptor


    【解决方案1】:

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

    【讨论】:

    • fflush 有效。但我试图在 fprintf 之后插入同步,并得到相同的结果(在 parent.out 中加倍开始)。为什么这不起作用?
    • 你能指定这个缓冲区在内核空间的什么位置吗?
    • 这与内核无关。使用FILE 的I/O 缓冲在标准库中,该标准库与您的代码链接,提供您的可执行程序。这意味着它发生在与您自己通过自己的代码缓冲它的级别相同的级别。缓冲区由您的程序在程序地址空间中物理分配,这就是fork 复制它们的原因。如果您不想使用这些缓冲区,请使用不带 f 的 I/O 函数,即 openwriteclose
    • 谢谢你的解释,我明白了
    • 谢谢@Marian。这完全符合我的预期。你刚刚拯救了我的一天:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-04
    • 1970-01-01
    相关资源
    最近更新 更多