c - 在 C 中,为什么我的程序在尝试通过管道传输多个命令时卡在 wait() 上?

标签 c pipe fork

我正在编写一个简单的程序来连接三个命令。对于每个命令,我 fork 一个子进程并在其中调用 execvp,而父进程等待 execvp 完成(注意,因为我 fork 了三次,所以我调用了 wait(NULL) 三次)

我创建了两个管道,pipe_A 和 pipe_Z。流程是这样的:

命令 1 将其输出写入 pipe_A, 命令 2 从 pipe_A 读取输入,然后将输出写入 pipe_Z,然后 命令 3 从 pipe_Z 读取输入,然后写入标准输出。

问题是程序在第二次等待(NULL)时卡住了。在我的代码中,它是紧跟在 'printf("reached\n"); 之后的行。该程序不会终止,并且会一直卡住,直到我发送中断。

如果我用同一个命令“echo hello”替换所有三个命令,它不会做太多但程序至少结束了。

我写了一个较小的程序(结构相同),只有两个命令(“echo hello”和“wc”),它也卡住了,就在第一次等待(NULL)时。但是,我注意到如果我在主程序的第二个命令上调用 execvp,输出会按预期打印。但是,该程序也会立即终止(因为 execvp),所以这不是我想要的方式。

我怀疑我犯了一个非常明显的错误,因为我不了解管道的工作原理或 wait(NULL) 函数调用的工作原理。

int main(){

//### COMMANDS AS STRING ARRAYS ###

    char * cmds1[3] = {"echo","hello", NULL};
    char * cmds2[3] = {"cat","-",NULL};
    char * cmds3[3] = {"wc", NULL};

//### CREATING PIPES ###

    int pipe_A[2];
    int pipe_Z[2];

    pipe(pipe_A);
    pipe(pipe_Z);

//### FIRST FORK FOR FIRST EXECVP ###

    int pid = fork();

    //Child process
    if(pid==0){

        close(pipe_A[0]);
        dup2(pipe_A[1], STDOUT_FILENO);

        execvp(cmds1[0],cmds1);
        exit(1);

    }

    //Parent process
    else if(pid >0){
        wait(NULL);
    }

//### SECOND FORK FOR SECOND EXECVP ###

    int pid2 = fork();

    //Child process
    if(pid2==0){

        close(pipe_A[1]);
        dup2(pipe_A[0],STDIN_FILENO);

        close(pipe_Z[0]);
        dup2(pipe_Z[1], STDOUT_FILENO); 

        execvp(cmds2[0],cmds2);
        exit(1);

    }

    //Parent process
    else if(pid2>0){

        printf("reached\n");
        wait(NULL);

    }

//### THIRD FORK FOR THIRD EXECVP ###

    int pid3 = fork();

    //Child process
    if(pid3==0){

        close(pipe_Z[1]);
        dup2(pipe_Z[0],STDIN_FILENO);

        execvp(cmds3[0],cmds3);
        exit(1);

    }

    //Parent process
    else if(pid2 >0){

        wait(NULL);

    }


//### END OF PROGRAM ###

    return 0;

预期输出为“1 1 6”,但程序没有终止。

最佳答案

你没有关闭父进程中管道的写端,所以它们都没有真正关闭,所以没有一个子进程得到 EOF,所以没有一个子进程(echo 除外 不读取输入)永远退出。

关于c - 在 C 中,为什么我的程序在尝试通过管道传输多个命令时卡在 wait() 上?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56572932/

相关文章:

gcc - 是否可以让 GCC 从管道中读取数据?

c - 使用 C 中的管道创建客户端和服务器时的奇怪行为

linux - 为什么我的命名管道输入命令行在被调用时挂起?

python - 为什么 if block 在 else 之后执行?

c++ - for 每个循环读取数组都是错误的

计算进程的内存使用

c - 使用 C 操作位时遇到问题

c++ - 具有缓冲能力的专用线程(每个连接一个线程)(c/c++)

c - 为什么 fork 我的进程导致文件被无限读取

c - 在继续之前等待 fork children 写入管道