我有以下代码,我使用管道在父进程和子进程之间进行双向读写。
根据我的阅读,如果我不使用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]);
}
}
答案 0 :(得分:1)
如果设置了O_NONBLOCK,则read()将返回-1并将errno设置为[EAGAIN]。
真正的问题是你在使用它们之前关闭文件描述符。例如,在子进程中,您正在关闭pipe_fds [1]并且您正在使用它来写一些值。在父进程中,您正在关闭pipe_fds [0],并且您正在使用它来读取某个值。一旦进程关闭文件描述符,该进程就不应该使用它来进行读取或写入。通常管道概念是一个进程(父进程或子进程)将使用管道创建的文件描述符之一进行写入,而另一个进程(父进程或子进程)将使用另一个文件描述符读取数据。