Search code examples
c++iooperating-systempipeblocking

Closing unused end in pipes


I was reading about pipes in my operating system course and writing some code to understand it better. I have a doubt regardign the following code:

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)
       ;
}

If I run this, the read is getting blocked, if I uncomment the close(fd[1]) command in the reader process, the code runs fine. That means close(fd[1]) closes the write end and read can proceed.

My doubt is even if i dont close the write end in reader process, it is getting closed at the end of the writer process. So why is still read sys call getting blocked?


Solution

  • Initially, both processes have open file descriptors to both the read and write ends of the pipe.

    The OS will only close an end of the pipe when all open file descriptors to it have been closed, so if you don't call close(fd[1]) in the child process one file descriptor will remain open, and the write end of the pipe will not be closed, and read will block waiting for input that will never come.