在分散和收集(即readv
和writev
)中,Linux读取了多个缓冲区,并从多个缓冲区中写入数据。
如果说,我有3个缓冲区的 vector ,则可以使用readv
,也可以使用单个缓冲区,该缓冲区的总大小为3个缓冲区,并执行fread
。
因此,我感到困惑:在哪些情况下应使用分散/聚集功能,何时应使用单个大缓冲区?
最佳答案
readv
,writev
提供的主要便利是:
writev
, vector 中的所有元素都将在一个连续的操作中写入,而其他进程完成的写入将不会在它们之间发生。 例如例如,您的数据自然是细分的,并且来自不同的来源:
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);
资料来源: