gpt4 book ai didi

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

转载 作者:IT老高 更新时间:2023-10-28 12:32:29 25 4
gpt4 key购买 nike

scattergather(即 readvwritev)中,Linux 读取多个缓冲区并从多个缓冲区。

如果说,我有一个包含 3 个缓冲区的向量,我可以使用 readv,或者我可以使用单个缓冲区,它具有 3 个缓冲区的组合大小并执行 fread.

因此,我很困惑:对于哪些情况应该使用分散/聚集,什么时候应该使用单个大缓冲区?

最佳答案

readvwritev提供的主要便利是:

  1. 它允许使用不连续的数据 block 。即缓冲区需要是数组的一部分,而是单独分配。
  2. I/O 是“原子的”。即如果您执行 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();

现在,所有三个“缓冲区”都不是一个大的连续 block 。但是无论出于何种原因,您都希望将它们连续写入文件(例如,它们是文件格式的文件头中的字段)。

如果你使用 write 你必须选择:

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

如果你使用 writev 代替,一切都很好:

  1. 您只进行了一次系统调用,而没有 memcpy 可以从三个中创建一个缓冲区。
  2. 此外,三个缓冲区是原子写入的,作为一个 block 写入。即如果其他进程也写入,则这些写入不会出现在三个向量的写入之间。

所以你会做这样的事情:

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

关于Linux:何时使用分散/收集 IO(readv、writev)与带有 fread 的大缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10520182/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com