8

我正在尝试了解系统调用的功能(此处vmsplice(2)的手册页)。关于标志的效果,我有两个问题:SPLICE_F_GIFT

  1. 手册页说,一旦将页面赠送给内核,就不能再修改内存。这是否意味着内存被永久固定,或者它可能指的是可以通过赠送过程取消映射的虚拟内存,而不是物理内存?换句话说,这个的典型用法是什么样的?

  2. 如果我不设置SPLICE_F_GIFTvmsplice(2)与矢量化写入系统调用有什么不同writev(2)吗?

4

2 回答 2

0

这是否意味着内存被永久固定,或者它可能指的是可以通过赠送过程取消映射的虚拟内存,而不是物理内存?换句话说,这个的典型用法是什么样的?

您承诺不修改该页面。不是页面的虚拟寻址。对于大多数用例,建议操作类似于:

mmap
read
vmsplice
munmap

通常,您希望使用mmapovermalloc来确保您有一个页面,而不仅仅是 4096 字节的 RAM。如果您的分配器确定它更有效,它可能位于 2MB 或 1GB 的中间。HUGE_PAGE

如果我不设置 SPLICE_F_GIFT,vmsplice(2)与矢量化写入系统调用有何不同writev(2)

是的

内核中的大多数缓冲区都是管道。或者实际上管道由与缓冲区相同的数据结构表示。

于 2017-02-17T17:43:40.983 回答
0

1 - 是的,它不同。
如果您使用 write 将 1GB 写入管道,它将循环直到将这些 1GB 传送到管道,除非信号中断工作。
如果你 vmsplice 1GB 到一个管道,它只会在管道缓冲区已满时阻塞,然后只写入管道缓冲区中可用的内容。
非常令人沮丧的是它没有循环并继续像常规写入一样写入。您不必复制,而是不得不进行一大堆 vmsplice 调用,并且必须为部分 vmsplice 写入实现一个循环。

2 - 我从 mmaped 区域进行 vmsplicing,并且能够在 vmsplicing 后立即进行 munmap,而不会崩溃或数据损坏。

于 2020-11-11T04:50:58.813 回答