Linux:何时使用分散/收集IO(readv,writev)与具有fread的大型缓冲区
在分散和收集 (即writev和writev )中,Linux读入多个缓冲区并从多个缓冲区写入。 
 如果说,我有一个3缓冲区的vector,我可以使用readv ,或者我可以使用一个单一的缓冲区,这是3个缓冲区的组合大小,做fread 。 
因此,我很困惑:对于哪些情况应该使用分散/聚集,何时应该使用一个大的缓冲区?
  writev , writev提供的主要便利是: 
- 它允许使用不连续的数据块。 即缓冲区不需要是数组的一部分,而是分开分配。
-   I / O是“primefaces”的。 即如果你写一个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你必须select: 
-  使用memcpy(overhead)将它们复制到一个内存块中,然后进行单个write调用。 然后写将是primefaces的。
-  进行三个独立的调用来write(开销)。 而且,来自其他进程的write调用可以在这些写入之间散布(不是primefaces的)。
 如果你使用writev代替,那么writev : 
-  你只需要进行一次系统调用,而不需要三个memcpy来创build一个缓冲区。
- 此外,三个缓冲区是primefaces写入,作为一个块写入。 即如果其他进程也写入,则这些写入不会进入三个向量的写入之间。
所以你会做这样的事情:
 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); 
资料来源: