Multi Forks由主母管控制

时间:2010-04-26 12:14:58

标签: c unix fork pipe

我有这个代码,它工作fin但是如果我更改NUM_CHILDREN = 2或任何其他数字“不等于1”它是坏文件描述符。那是为什么?

#include <stdio.h>
#include <unistd.h>

enum {
    NUM_CHILDREN = 1
};

static int pipes[NUM_CHILDREN][2];

void start_encoding(void) {
    pid_t d, h;

    int pipe_master[2];
    pipe(pipe_master);
    if (d = fork()) {
        int j;
        for (j = 0; j < NUM_CHILDREN; j++) {
            int pipe_sub[2];
            pipe(pipe_sub);
            pipes[j][0] = pipe_sub[0];
            pipes[j][1] = pipe_sub[1];
            if (h = fork()) {
                dup2(pipes[j][0], 0);
                close(pipe_master[0]);
                close(pipe_master[1]);
                for (j = 0; j < NUM_CHILDREN; j++) {
                    close(pipes[j][0]);
                    close(pipes[j][1]);
                }
                execl("/bin/sort", "sort", NULL);
            } else {
                close(STDIN_FILENO);
                dup2(pipe_master[0], STDIN_FILENO);
                close(STDOUT_FILENO);
                dup2(pipes[j][1], STDOUT_FILENO);
                close(pipe_master[0]);
                close(pipe_master[1]);
                for (j = 0; j < NUM_CHILDREN; j++) {
                    close(pipes[j][0]);
                    close(pipes[j][1]);
                }
                execl("/bin/sed", "sed", "s/tty/TTY/g", NULL);
            }
        }
    } else {
        close(STDOUT_FILENO);
        dup2(pipe_master[1], STDOUT_FILENO);
        close(pipe_master[0]);
        close(pipe_master[1]);
        execl("/usr/bin/who", "who", NULL);
    }
} 

其实我想要模拟:

             -- sed
        |---|
        |    -- sort
  who --|
        |    -- sed
        |---|
        |    -- sort
        |
         --- ...

我应该使用什么?

2 个答案:

答案 0 :(得分:1)

因为在这些嵌套循环中:

for (j = 0; j < NUM_CHILDREN; j++) {
    close(pipes[j][0]);
    close(pipes[j][1]);
}

您正在尝试关闭尚未创建的文件描述符。你也不能在这里重复使用j - 你需要为这些内部循环使用不同的变量。

答案 1 :(得分:0)

此代码:

    for (j = 0; j < NUM_CHILDREN; j++) {
...
      if (h = fork()) {
...
            for (j = 0; j < NUM_CHILDREN; j++) {
                close(pipes[j][0]);
                close(pipes[j][1]);
            }
            execl("/bin/sort", "sort", NULL);

是否会尝试关闭尚未打开的管道(如果NUM_CHILDREN&gt; 1)

对内圈和外圈使用相同的循环变量(j)也是一个问题。

另一个问题是你正在从中进行execl("/bin/sort"),所以外部循环永远不会超过第一次迭代。