【问题标题】:Closing unused end in pipes关闭管道中未使用的末端
【发布时间】:2018-09-17 19:08:10
【问题描述】:

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

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]) 关闭写入端并且可以继续读取。

我的疑问是,即使我没有在读取器进程中关闭写入端,它也会在写入器进程结束时关闭。那么为什么 read sys 调用仍然被阻塞?

【问题讨论】:

    标签: c++ io operating-system pipe blocking


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      两个问题:

      第一个是由于operator precedence,循环条件n_bytes=read(fd[0],&amp;arr[i],sizeof(int))&gt;0实际上等于n_bytes = (read(fd[0],&amp;arr[i],sizeof(int)) &gt; 0)。也就是说,您将 comparison 的值分配给变量 n_bytes。要更正此问题,请在分配周围添加额外的括号,如 (n_bytes=read(fd[0],&amp;arr[i],sizeof(int)))&gt;0

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-01-26
        • 2014-09-06
        • 1970-01-01
        • 2018-12-02
        • 1970-01-01
        • 1970-01-01
        • 2014-11-24
        • 2018-07-20
        相关资源
        最近更新 更多