pipe-fork-c-为什么程序无响应无任何错误?

时间:2018-08-19 18:04:44

标签: c pipe fork dup2

嗨,我正在编写一个程序来执行cat input.txt |排序uniq在c编程中使用pipe,fork和dup2,但是该程序似乎根本不运行任何东西。我在main()之后的开头放置了一个printf,但仍然看不到任何输出。我不知道后台发生了什么或者为什么会这样?

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

int main(){
    printf("we are here");
    int pipe1[2];
    int pipe2[2];
    if(pipe(pipe1)==-1){
        perror("failed to pipe\n");
        exit(1);
    }


    int process1=fork();

    if(process1<0){
        perror("failed to create the first child1\n");
        exit(1);
    }else if(process1>0){
        if(close(pipe1[0])==-1){
            perror("failed to close the first pipe read\n");
            exit(1);
        }

        if(dup2(pipe1[1],1)==-1){
            perror("failed to duplicate\n");
            exit(1);
        }

        if(close(pipe1[1])==-1){
            perror("failed to close the first pipe write\n");
            exit(1);
        }

        execlp("cat","cat","inputs.txt",NULL);
        perror("failed to exec\n");
        exit(1);
    }else if(process1==0){
        if(pipe(pipe2)==-1){
            perror("failed to pipe\n");
            exit(1);
        }

        int process2=fork();

        if(process2<0){
            perror("failed to create the first child1\n");
            exit(1);
        }else if(process2==0){

            if(close(pipe2[1])==-1){
                perror("failed to close the second pipe write-third process\n");
                exit(1);
            }

            if(dup2(pipe2[0],0)==-1){
                perror("failed to duplicate\n");
                exit(1);
            }

            if(close(pipe2[0])==-1){
                perror("failed to close the second pipe read-third process\n");
                exit(1);
            }

            execlp("uniq","uniq",NULL);
            perror("failed to exec\n");
            exit(1);
        }else if(process2>0){
            if(close(pipe1[1])==-1){
                perror("failed to close the first pipe write\n");
                exit(1);
            }
            if(close(pipe2[0])==-1){
                perror("failed to close the second pipe read\n");
                exit(1);
            }

            if(dup2(pipe1[0],0)==-1){
                perror("failed to duplicate\n");
                exit(1);
            }

            if(dup2(pipe2[1],1)==-1){
                perror("failed to duplicate\n");
                exit(1);
            }

            if(close(pipe1[0])==-1){
                perror("failed to close the first pipe read\n");
                exit(1);
            }

            if(close(pipe2[1])==-1){
                perror("failed to close the second pipe write\n");
                exit(1);
            }

            execlp("sort","sort",NULL);
            perror("failed to exec\n");
            exit(1);
        }
    }


}

1 个答案:

答案 0 :(得分:2)

  1. printf实际上并不会立即打印-只是将内容放入缓冲区中以便以后打印,无论是在缓冲区填充或过程结束时,还是在换行符中放入换行符时缓冲。由于您什么都不做,因此它永远不会出现。您可以使用fflush(stdout);来刷新缓冲区,如果可能存在缓冲数据,通常在调用fork之前这样做是个好主意-否则,该缓冲区将被分叉,因此其内容可能会显示出来两次。

  2. 在执行“ uniq”之前,您永远不会在孙子中关闭pipe1。由于pipe1是“ sort”程序的输入,因此它将永远不会获得EOF,并且sort永远不会终止。因此,您的程序似乎无能为力。

  3. “ uniq”在孙子代中运行,并输出到stdout,(可能是?)终端。如果父(猫)首先退出(这很可能会退出),那么外壳将再次获得控制权,并且可以从“ uniq”下切换出控制终端。这可能会导致uniq被停止,从而降低了您的终端设置。默认情况下,在大多数系统上,这种情况不会发生(uniq只会在shell提示后愉快地写到终端,这可能会导致output_令人困惑,但可能会这样。