代码之家  ›  专栏  ›  技术社区  ›  Arka Pal

关闭管道中未使用的端部

  •  2
  • Arka Pal  · 技术社区  · 6 年前

    我在操作系统课程中阅读了有关管道的内容,并编写了一些代码来更好地理解它。我对以下代码有疑问:

    int fd[2];              // CREATING PIPE
    pipe(fd);
    int status;
    
    int pid=fork();
    if(pid==0)
    {
         // WRITER PROCESS
    
        srand(123);
        int arr[3]={1,2,3};
    
        close(fd[0]);                   // CLOSE UNUSED(READING END)
        for(int i=0;i<3;i++)
          write(fd[1],&arr[i],sizeof(int));
        close(fd[1]);                   // CLOSE WRITING END AFTER WRITING SO AS READ GETS THE EOF
    }
    else
    {
        // READER PROCESS
    
        int arr[10];
    
        int  i=0;
        int n_bytes;
        //close(fd[1]);                   // CLOSE UNUSED(WRITING END)
        while((n_bytes=read(fd[0],&arr[i],sizeof(int)))>0)        // READIN IN A LOOP UNTIL END
            i++;
        close(fd[0]);                   // CLOSE READING END after reading
        for(int j=0;j<i;j++)
            cout<<arr[j]<<endl;
        while(wait(&status)>0)
           ;
    }
    

    如果我运行这个命令,读取就会被阻止,如果我在读卡器进程中取消对close(fd[1])命令的注释,代码就会正常运行。 这意味着close(fd[1])关闭写入端,读取可以继续。

    我的怀疑是 即使我没有在reader进程中关闭write端,它也会在writer进程的末尾关闭。那么,为什么read sys调用仍然被阻止?

    2 回复  |  直到 6 年前
        1
  •  4
  •   Miles Budnek    6 年前

    最初,这两个进程在管道的读写端都有打开的文件描述符。

    只有当管道的所有打开的文件描述符都已关闭时,操作系统才会关闭管道的一端,因此如果不调用 close(fd[1]) 在子进程中,一个文件描述符将保持打开状态,管道的写入端将不会关闭,并且 read 将阻止等待永远不会出现的输入。

        2
  •  0
  •   Some programmer dude    6 年前

    两个问题:

    首先是由于 operator precedence 循环条件 n_bytes=read(fd[0],&arr[i],sizeof(int))>0 真的是平等的 n_bytes = (read(fd[0],&arr[i],sizeof(int)) > 0) 。也就是说,您分配 比较 到变量 n_bytes 。若要更正此问题,请在作业周围添加额外的括号,如 (n_bytes=read(fd[0],&arr[i],sizeof(int)))>0

    第二个问题是,父母双方 子进程将调用 wait 在循环中。您应该只在父进程中执行此操作,以等待子进程。