在C中为一个父级创建多个子进程

时间:2014-04-01 00:33:26

标签: c children

所以我一直在为我的OS类编写代码,在我的项目中,我必须为命令行上的每个文件创建一个新的子进程,并将子信息从子进程传递给父进程。我们应该重新创建Unix的wc实用程序(我已经处理过这部分)。

到目前为止,我所尝试的是:

            for(i=0; i<argcount; i++){
                    int pid;
                    pid = fork();
                    if(pid == 0){
                            /* Child Process */
                            /* Close read pipes */
                            close(l_pipe[0]);
                            close(w_pipe[0]);
                            close(c_pipe[0]);
                            wc(lflag, wflag, cflag, filenames[i]);
                    } else {
                            /* Parent Process for piping */
                            /* Close write pipes */
                            close(l_pipe[1]);
                            close(w_pipe[1]);
                            close(c_pipe[1]);

                            /* Read from pipes */
                            read(l_pipe[0], &buffer, sizeof(count_t));
                            lines+=buffer;

                            read(w_pipe[0], &buffer, sizeof(count_t));
                            words+=buffer;

                            read(c_pipe[0], &buffer, sizeof(count_t));
                            bytes+=buffer;
                    }
            }

然而,这会产生与孩子一样多的父母,这显然是错误的。我不确定我应该在哪里分叉。我在子进程和父进程之间使用管道,并且我确定父进程需要read()与子write()s一样多次。

感谢您提供任何建议。

2 个答案:

答案 0 :(得分:1)

我立即注意到了一些事情。

  • 在您的子流程分支中,您未在_exit()之后致电wc()。这意味着您的子进程将循环并为更多的孩子开始分叉。

  • 在您的父进程分支中,您正在等待刚刚生成的子进程的响应,然后再继续创建下一个子进程。所以基本上你已经序列化了这个过程,并且不会利用多个过程。

答案 1 :(得分:1)

除了Greg Hewgillanswer中提出的问题,我还会发现以下问题:

  1. 您可以使用循环分支并运行子进程,而父代部分只需返回循环的下一次迭代。
  2. 然后你会有一个循环来读取管道。
  3. 在该循环之前,父进程将关闭所有三个管道的写入端(否则它将永远不会在管道上看到EOF)。
  4. 从管道读取的循环应依次从每个管道读取,而不是依次排放每个管道。
  5. 我假设您有count_t buffer; - 它有助于显示变量声明。如果您有某种char buffer[sizeof(count_t)],那么您会遇到各种各样的问题,无论大小。
  6. 当您在当前方案中创建第二个子节点时,管道的写入端都将关闭,因此第二个和后续子节点将无法向父节点发送任何内容。您必须移动三个调用才能关闭管道的写入端,以使其位于循环之外。
  7. 您的管道必须位于全局变量中,以便wc函数可以使用它们。这不是世界末日,但通常更整洁,以避免全球变量。这是一个二阶问题;你还有其他更重要的问题需要先解决。
  8. 如果您需要将尺寸与单个文件相关联,则需要执行更多记账。目前,您只汇总总计。在这种情况下,您当前的同步设计可能是合适的。如果不这样做,你就让孩子们在一次操作中写一个PID或另一个ID号加上管道上的计数(以确保操作是原子的)。单独的写操作不是交错的,除非它们对于管道的内部缓冲区来说太大了,这对于几个整数来说不会有问题。