c语言 - 不能管道三个进程



我一直在尝试在c中实现以下命令:cat/etc/passwd|cut–f1–d:|sort

这是我目前掌握的代码。第一个管道工作正常,但第二个管道似乎根本不工作。

我已经反复检查了代码,但没有发现任何错误。有人能提供一个能解决我问题的建议吗?

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
    {
        int pipe_A[2];
        int pipe_B[2];
        pipe(pipe_A);
        pipe(pipe_B);
        pid_t pid_A, pid_B, pid_C;
        if( !(pid_A = fork()) ) {
            close(1);       /* close normal stdout */
            dup(pipe_A[1]);   /* make stdout same as pipe_A[1] */
            close(pipe_A[0]); /* we don't need this */
            execlp("/bin/cat", "cat", "/etc/passwd" ,  NULL);
        }
        if( !(pid_B = fork()) ) {
            close(0);       /* close normal stdin */
            dup(pipe_A[0]);   /* make stdin same as pipe_A[0] */
            close(pipe_A[1]); /* we don't need this */
            close(1);   /* close normal stdout */
            dup(pipe_B[1]);   /* make stdout same as pipe_B[1] */
            close(pipe_B[0]); /* we don't need this */
            execlp("/usr/bin/cut", "cut", "-f1", "-d:", NULL);
       }
       if( !(pid_C = fork()) ) {
            close(0);       /* close normal stdin */
            dup(pipe_B[0]);   /* make stdin same as pipe_B[0] */
            close(pipe_B[1]); /* we don't need this */
            execlp("/usr/bin/sort", "sort", NULL);
       }
    return 0;
}

谢谢。

问题是到处都是打开的FD。请注意,每次调用fork时,所有打开的管道都由子进程继承,但具有重复FD的管道不能正常工作。

例如,cat继承了pipe_B的读取和写入FD。同样地,sort正在继承pipe_A的两个FD。

正确的方法是沿着以下路线(但我建议使用dup2()):

int main(void)
{
    int pipe_A[2];
    int pipe_B[2];
    pid_t pid_A, pid_B, pid_C;
    pipe(pipe_A);
    if( !(pid_A = fork()) ) {
        close(pipe_A[0]); // A-read not needed here
        close(1);
        dup(pipe_A[1]);
        close(pipe_A[1]); //do not pass A-write twice
        execlp("/bin/cat", "cat", "/etc/passwd" ,  NULL);
    }
    close(pipe_A[1]); // A-write not needed anymore
    pipe(pipe_B); //do not create this pipe until needed
    if( !(pid_B = fork()) ) {
        close(pipe_B[0]); // B-read not needed here
        close(0);
        dup(pipe_A[0]);
        close(pipe_A[0]); //do not pass A-read twice

        close(1);
        dup(pipe_B[1]);
        close(pipe_B[1]); //do not pass B-write twice
        execlp("/usr/bin/cut", "cut", "-f1", "-d:", NULL);
   }
   close(pipe_A[0]); // A-read not needed anymore
   close(pipe_B[1]); // B-write not needed anymore
   if( !(pid_C = fork()) ) {
        close(0);
        dup(pipe_B[0]);
        close(pipe_B[0]); // do not pass B-read twice
        execlp("/usr/bin/sort", "sort", NULL);
   }
   close(pipe_B[0]); // B-read not needed anymore
   return 0;
}

如果您分析我的代码(如果我写对了),假设父进程只有FD 0、1和2,那么每个execlp()将恰好得到3个FD,0、1、2。

最新更新