在scatter和gather(即readv
和writev
)中,Linux读入多个缓冲区,并从多个缓冲区写入.
如果说,我有一个3个缓冲区的向量,我可以使用readv
,或者我可以使用一个缓冲区,它的大小是3个缓冲区和do fread
的总和.
因此,我感到困惑:在哪些情况下应该使用分散/聚集,何时应该使用单个大缓冲区?
在scatter和gather(即readv
和writev
)中,Linux读入多个缓冲区,并从多个缓冲区写入.
如果说,我有一个3个缓冲区的向量,我可以使用readv
,或者我可以使用一个缓冲区,它的大小是3个缓冲区和do fread
的总和.
因此,我感到困惑:在哪些情况下应该使用分散/聚集,何时应该使用单个大缓冲区?
readv
writev
提供的主要便利是:
writev
,向量中的所有元素都将在一个连续操作中写入,而其他进程所做的写入操作将不会发生在它们之间.e、 g.比如说,你的数据是自然分割的,并且来自不同的来源:
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
,则必须在以下选项中进行 Select :
memcpy
(开销)将它们复制到一个内存块中,然后进行一次write
调用.然后写入将是原子的.write
(开销).此外,来自其他进程的write
个调用可以在这些写入之间穿插(不是原子的).如果你用writev
来代替,这一切都很好:
所以你可以这样做:
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);
资料来源: