多管C程序不起作用

时间:2014-10-25 17:09:31

标签: c linux unix pipe

我决定编写一个简单的硬编码c程序来更好地理解管道是如何工作的。 该程序有3个命令: 找 。 -name' ' | sed' s /.*。。|排序

它适用于1个管道(如果我只使用2个命令)但是它失败了2个管道(排序只是没有得到信息)。

我认为错误是关闭或waitpid,但我已经尝试了一切(我能想到)但它仍然无效。我错过了什么? 我使用的信息:

Is it possible to have pipe between two child processes created by same parent (LINUX, POSIX)

http://www.quora.com/Unix/How-can-I-write-a-code-for-PIPE-in-C-shell-script-python< - Sams例子

Implementation of multiple pipes in C

编辑: 命令写得没有错误。问题肯定不在其中(因为如果我只使用1个管道它们可以工作) 我的代码:

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

int main(int argc, char* argv[]) {


    pid_t test, test2, test3;
    int old_pipe[2];
    int new_pipe[2];


    //test command
    //char *argv1[] = {"ls", "-1", "-h", NULL};
    char *argv1[] = {"find", ".", "-name", "*.*",NULL};
    char *argv2[] = {"sed", "s/.*\\.//", NULL};
    char *argv3[] = {"sort", NULL};

    //creates a pipe
    pipe(old_pipe);
    pipe(new_pipe);

    test = fork();
    if(test == 0){
        dup2(old_pipe[1], 1);
        close(old_pipe[0]);

        execvp(argv1[0], argv1);
            perror("exec");
            return 1;
    }

    test2 = fork();
    if(test2 == 0){
        dup2(old_pipe[0], 0);
        close(old_pipe[1]);
        dup2(new_pipe[1], 1);
        close(new_pipe[0]);

        execvp(argv2[0], argv2);
            perror("exec");
            return 1;
    }


    test3 = fork();
    if(test3 == 0){
        dup2(new_pipe[0], 0);
        close(new_pipe[1]);

        execvp(argv3[0], argv3);
        perror("exec");
        return 1;
    }

    close(old_pipe[0]);
    close(old_pipe[1]);

    close(new_pipe[0]);
    close(new_pipe[1]); 

    waitpid(test);
    waitpid(test2);
    waitpid(test3);

    return 0;
}

1 个答案:

答案 0 :(得分:1)

你的第3个执行官(开始“排序”)没有关闭old_pipe[1]并保持打开状态。 sed将无法看到EOF并保持活力。你应该很晚才打电话给pipe(2)

我建议调查/proc/<pid>/fd resp。使用lsof查看哪些文件描述符是打开的。例如。之后

    dup2(old_pipe[1], 1);
    close(old_pipe[0]);

如果不是old_pipe[1],则应关闭1

更多解释(如评论中所述):你的程序有

pipe(old_pipe);
pipe(new_pipe);

test = fork();
   /* --> 'find'; writes into old_pipe[1] */
test2 = fork();
   /* --> 'sed'; reads from old_pipe[0], writes into new_pipe[1] */
test3 = fork();
   /* --> 'sort'; reads from new_pipe[0] */

只要输入(test2)打开,old_pipe[0]程序就不会退出。因为test3(等待test2完成)此管道处于活动状态,所以它将死锁。

关闭子分支中的fds不会在父进程中关闭它们。