为什么 grep 会进入阻塞阶段?

为什么 grep 会进入阻塞阶段?

我正在做一个测试,我的任务是一个孩子将输出管道化到另一个孩子的输入。我正在使用ps -ef第一个命令(通过使用execlp())grep root作为第二个命令(bu using execlp())。我得到了所需的输出,但我在执行 grep 的进程中被阻止。我已使用 top 命令来验证当前正在运行的进程。

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<fcntl.h>

int main(){
    int status,i;
    int fds[2];
    pid_t pid;
    //pid=fork();;
    if(pipe(fds)==-1){
        perror("Error:");
        exit(0);
    }
    if(fork()>0){
        printf("The pid of the parent is %d\n",getpid());
        if(fork()==0){

            printf("The PID of the 2nd child %d\n",getpid());
            //printf("Inside 2nd child\n");
            close(0);
            dup(fds[0]);
            close(fds[1]);
            //fcntl(fds[0],F_SETFD,FD_CLOEXEC);
            //printf("The PID of the 2nd child %d\n",getpid());
            if(execlp("grep","grep","root",NULL)==-1){
                perror("ERROR FROM SECOND CHILD: ");
                exit(1);
            }

        }
        else{
            printf("The parent is waiting\n");
            /*for(i=0;i<2;i++){
                printf("%d The PID OF THE EXIT CHILD is %d\n",i,wait(&status));
            }*/
            while(wait(NULL)>0)
                perror("Error From Main:\n");
            //wait(&status);
            printf("The parent exited from the waiting stage\n");
            return 0;
        }

        //while(1);
    }
    else{
        close(1);
        dup(fds[1]);
        close(fds[0]);
        //close(1);
        printf("The pid of the First child is %d\n",getpid());
        if(execlp("ps","ps","-ef",NULL)==-1){
            perror("Error:");
            exit(1);
        }

    }

}

请帮助我。因为我正在制作外壳。执行此任务是必要的。

答案1

grep 进程被阻止,因为它没有从管道的其他写入端获取 EOF。当关联的写入文件(fds[1])描述符将关闭时,EOF 将发送到读取器端。我的错误是我没有尽管我已经从正在写入管道的进程中关闭了它,但从父进程(main)关闭了写入描述符(fds[1])。

所以可能会出现这样的问题:即使我们不使用描述符,我们是否也需要关闭它?是的,是的!因为父进程和子进程具有相同的描述符副本,这些描述符基本上是内存引用(我不确定)。因此,即使我们从一个进程关闭,另一个副本也可能在另一个进程中打开,这可能会阻塞第三个进程可能正在从管道中读取数据。

我通过使用 cat /proc// 研究文件描述符来进行调试。

相关内容