首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Linux:何时使用分散/聚集IO (readv、writev)与使用fread的大缓冲区

Linux:何时使用分散/聚集IO (readv、writev)与使用fread的大缓冲区
EN

Stack Overflow用户
提问于 2012-05-10 00:24:48
回答 1查看 32.4K关注 0票数 75

在分散和聚集(即readvwritev)中,Linux从多个缓冲区读取数据并从多个缓冲区写入数据。

假设我有一个有3个缓冲区的向量,我可以使用readv,或者我可以使用一个缓冲区,它的大小是3个缓冲区的总和,然后执行fread

因此,我感到困惑:在哪些情况下应该使用分散/聚集,以及何时应该使用单个大型缓冲区?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-05-10 01:07:20

readvwritev提供的主要便利是:

  1. 它允许处理不连续的数据块。也就是说,缓冲区不需要是数组的一部分,而是单独分配的。
  2. I/O是‘原子’的。例如,如果您执行writev,则向量中的所有元素都将在一个连续的操作中写入,其他进程的写入将不会在它们之间发生。

例如,你的数据自然是分段的,并且来自不同的来源:

代码语言:javascript
复制
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,则必须在以下两种情况之间进行选择:

  1. 使用memcpy (开销)将它们复制到一个内存块中,然后执行一次write调用。然后,写入将是对write的三个单独的调用(开销)。此外,来自其他进程的write调用可以散布在这些写操作之间(而不是原子的)。

如果你改用writev,一切都很好:

  1. 你只做了一个系统调用,没有memcpy从三个系统调用中创建一个单独的缓冲区。
  2. 另外,这三个缓冲区是原子写入的,作为一个块写入。即,如果其他进程也写入,则这些写入将不会出现在三个向量的写入之间。

因此,您将执行以下操作:

代码语言:javascript
复制
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);

资料来源:

  1. http://pubs.opengroup.org/onlinepubs/009604499/functions/writev.html
  2. http://linux.die.net/man/2/readv
票数 110
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10520182

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档