管道上的read()没有阻塞

时间:2017-03-16 12:36:12

标签: c++ linux embedded-linux

我有以下代码,我使用管道在父进程和子进程之间进行双向读写。

根据我的阅读,如果我不使用O_NONBLOCK,读取应该阻塞,直到数据从另一端写入管道。

但是,我注意到父方的阅读没有阻止。我知道,因为我在gdb中调试,所以我把睡眠作为孩子内部的第一个语句。

为什么父母的read()不会阻止?另外,在两个进程之间是否需要执行其他任何同步读/写的操作?

typedef struct
{
    int x;
    int y;
}PayLoad;

PayLoad pl;
bool b = false;

int pipe_fds[2];


void p(int i, int j)
{
   pl.x = i;
   pl.y = j;

   pipe(pipe_fds);
   pid_t cpid = fork();

   if (cpid == 0) // child process
   {
       std::this_thread::sleep_for(std::chrono::seconds(100)); // just for debugging
       close(pipe_fds[1]);
       read(pipe_fds[0], &pl, sizeof(Payload));
       //... do some processing on read data

       close(pipe_fds[0]);
       write(pipe_fds[1], &b, sizeof(bool));
       close(pipe_fds[1]);
   }
   else if (cpid > 0) // parent process
   {
       close(pipe_fds[0]);
       write(pipe_fds[1], &pl, sizeof(Payload));
       close(pipe_fds[1]);
       read(pipe_fds[0], &b, sizeof(bool));  <------ did not block!
       close(pipe_fds[0]);
   }
}

1 个答案:

答案 0 :(得分:1)

如果设置了O_NONBLOCK,则read()将返回-1并将errno设置为[EAGAIN]。

真正的问题是你在使用它们之前关闭文件描述符。例如,在子进程中,您正在关闭pipe_fds [1]并且您正在使用它来写一些值。在父进程中,您正在关闭pipe_fds [0],并且您正在使用它来读取某个值。一旦进程关闭文件描述符,该进程就不应该使用它来进行读取或写入。通常管道概念是一个进程(父进程或子进程)将使用管道创建的文件描述符之一进行写入,而另一个进程(父进程或子进程)将使用另一个文件描述符读取数据。