GNU库手册简要提到,管道的读写都是原子性
如果写入的数据大小不大于PIPE_BUF,则读取或写入管道数据是原子的。
但是,与man 7管一样,Linux上的手册页没有提到读取是原子的,并且男子2读显式声明,如果读取被信号中断,读取的返回量可能小于请求的数量。
那么,在Linux上,对读取长度为PIPE_BUF
的管道的读取调用是否真正是原子的呢?
特别是,如果管道的单个写入器总是写入(例如,12字节块),并且管道中有两个并发读取器,这些读取器读取管道的字节数为12字节,这些读取器是得到准确的12字节读,还是得到类似EAGAIN
的错误,而不可能得到部分读取?
另外,当作者用12字节块写入,但并发读取器试图同时读取PIPE_BUF/12
块时,情况又如何呢?那么,成功的读取是否总是返回精确的12字节乘数,还是可以返回任意数量的字节?
发布于 2017-02-23 00:29:32
从源代码来看,pipe_read
在source/fs/pipe.c
内核中的实现发生了很大变化,但是通过快速阅读2.0.40、2.4.37、2.6.32、3.11和4.9中的代码,在我看来,每当出现(或者是,当read
阻塞时)大小为w的写入和大小为r>w的读取时,read
至少会返回w字节。因此,如果您有固定大小的块(小于PIPE_BUF
的大小),并且总是使读取的大小相同,那么在实践中可以保证始终读取整个块。
另一方面,如果你有可变大小的块,那么你就没有这样的保证.只有在编写方面才有原子性的保证:小于PIPE_BUF
的写入不会被另一个作者删减。但是在读取器方面,如果有10个字节的写入,然后是20个字节的写入,然后尝试读取15个字节,那么您将得到第一次写入和第二次写入的前5个字节。read
调用不会停止读取数据,直到它不得不阻塞或其输出缓冲区已满为止。
如果要以块形式传输数据,请使用数据报插座而不是管道。
https://unix.stackexchange.com/questions/346755
复制相似问题