vmsplice(2)的语义是什么,有和没有gift



我试图理解vmsplice(2)系统调用的功能(手册页在这里)。关于SPLICE_F_GIFT标志的作用,我有两个问题:

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

  2. 如果我不设置SPLICE_F_GIFT, vmsplice(2)writev(2)这样的矢量化写系统调用有什么不同吗?

1 -是的,这是不同的。
如果使用write将1GB写入管道,它将循环,直到这1GB被传递到管道,除非有信号中断该工作。
如果您将1GB的内存拼接到一个管道中,那么只有当管道缓冲区已满时,它才会阻塞,然后只写管道缓冲区中可用的内容。
非常令人沮丧的是,它没有循环并继续像常规写作一样写作。你可以用不复制来换取大量的vmsplice调用,并且必须为部分vmsplice写入实现循环。

2 -我从映射区域进行vmsplicing,并且能够在vmsplicing后立即munmap,没有崩溃或数据损坏

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

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

mmap
read
vmsplice
munmap

通常你想使用mmap而不是malloc,因为你想确保你有一个页面,而不仅仅是4096字节的RAM。哪个可以位于2MB或1GB HUGE_PAGE的中间,如果分配器认为这样更有效的话。

如果我不设置SPLICE_F_GIFT, vmsplice(2)writev(2)这样的矢量化写系统调用有什么不同吗?

是的

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

最新更新