管道上的 read() 没有阻塞
read() on a pipe is not blocking
我有以下代码,我在 parent 和 child 进程之间使用管道进行双向读写。
据我所知,如果我不使用 O_NONBLOCK,读取应该会阻塞,直到数据从另一端写入管道。
但是,我注意到 parent 端的读取没有阻塞。我知道,因为我在 gdb 中调试,所以我在 child 中将睡眠作为第一个语句。
为什么 parent 的 read() 没有阻塞在这里?另外,我还需要做些什么来同步两个进程之间的 read/write 吗?
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]);
}
}
如果设置了 O_NONBLOCK,read() 将 return a -1 并将 errno 设置为 [EAGAIN]。
真正的问题是您在使用文件描述符之前关闭了它们。例如,在子进程中,您正在关闭 pipe_fds[1] 并使用它来写入一些值。在父进程中,您正在关闭 pipe_fds[0] 并使用它来读取一些值。进程关闭文件描述符后,进程不应使用它进行读取或写入。通常管道概念是一个进程(父进程或子进程)将使用管道创建的文件描述符之一写入,而另一个进程(父进程或子进程)将使用另一个文件描述符读取数据。
我有以下代码,我在 parent 和 child 进程之间使用管道进行双向读写。
据我所知,如果我不使用 O_NONBLOCK,读取应该会阻塞,直到数据从另一端写入管道。
但是,我注意到 parent 端的读取没有阻塞。我知道,因为我在 gdb 中调试,所以我在 child 中将睡眠作为第一个语句。
为什么 parent 的 read() 没有阻塞在这里?另外,我还需要做些什么来同步两个进程之间的 read/write 吗?
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]);
}
}
如果设置了 O_NONBLOCK,read() 将 return a -1 并将 errno 设置为 [EAGAIN]。
真正的问题是您在使用文件描述符之前关闭了它们。例如,在子进程中,您正在关闭 pipe_fds[1] 并使用它来写入一些值。在父进程中,您正在关闭 pipe_fds[0] 并使用它来读取一些值。进程关闭文件描述符后,进程不应使用它进行读取或写入。通常管道概念是一个进程(父进程或子进程)将使用管道创建的文件描述符之一写入,而另一个进程(父进程或子进程)将使用另一个文件描述符读取数据。