在分散和聚集(即readv
和writev
)中,Linux 读取多个缓冲区并从多个缓冲区写入。
如果说,我有一个包含 3 个缓冲区的向量,我可以使用readv
,或者我可以使用单个缓冲区,该缓冲区的组合大小为 3 个缓冲区并执行fread
.
因此,我很困惑:对于哪些情况应该使用 scatter/gather 以及何时应该使用单个大缓冲区?
readv
提供的主要便利writev
是:
writev
,则向量中的所有元素都将写入一个连续的操作中,并且其他进程完成的写入不会发生在它们之间。例如,您的数据是自然分段的,并且来自不同的来源:
struct foo *my_foo;
struct bar *my_bar;
struct baz *my_baz;
my_foo = get_my_foo();
my_bar = get_my_bar();
my_baz = get_my_baz();
现在,所有三个“缓冲区”都不是一个大的连续块。但是无论出于何种原因,您都希望将它们连续写入文件(例如,它们是文件格式的文件头中的字段)。
如果你使用write
你必须选择:
memcpy
,然后进行一次write
调用。然后写入将是原子的。write
对(开销)进行三个单独的调用。此外,write
来自其他进程的调用可以散布在这些写入之间(不是原子的)。如果您writev
改用,一切都很好:
memcpy
从三个中创建一个缓冲区。所以你会做这样的事情:
struct iovec iov[3];
iov[0].iov_base = my_foo;
iov[0].iov_len = sizeof (struct foo);
iov[1].iov_base = my_bar;
iov[1].iov_len = sizeof (struct bar);
iov[2].iov_base = my_baz;
iov[2].iov_len = sizeof (struct baz);
bytes_written = writev (fd, iov, 3);
资料来源: