我试图理解vmsplice(2)
系统调用(手册页here)的功能。我有两个关于SPLICE_F_GIFT
标志效果的问题:
手册页说,一旦您将页面提供给内核,就不能再次修改内存。这是否意味着内存永远固定,或者它可能是指可以通过赠送过程而不是物理内存取消映射的虚拟内存?换句话说,这个的典型用途是什么样的?
如果我没有设置SPLICE_F_GIFT
,vmsplice(2)
是否与writev(2)
之类的矢量化写入系统调用有什么不同?
答案 0 :(得分:0)
这是否意味着内存永远被固定,或者是否可能是指可以通过赠送过程而不是物理内存取消映射的虚拟内存?换句话说,它的典型用途是什么样的?
您承诺不修改页面。不是页面的虚拟寻址。对于大多数用例,建议操作类似于:
mmap
read
vmsplice
munmap
通常,您希望使用mmap
而不是malloc
,因为您希望确保拥有一个页面,而不仅仅是4096字节的RAM。如果您的分配器确定更高效,那么可以位于2MB或1GB HUGE_PAGE
的中间。
如果我没有设置SPLICE_F_GIFT,
vmsplice(2)
是否与writev(2)
之类的矢量化写入系统调用不同?
是
内核中的大多数缓冲区都是管道。或者真正的管道由与缓冲区相同的数据结构表示。
答案 1 :(得分:0)
1-是的,与众不同。
如果您通过写操作将1GB写入管道,它将一直循环直到将1GB传送到管道,除非有信号中断工作。
如果将vmsplice 1GB分配给管道,则只有在管道缓冲区已满时才会阻塞,然后仅将可用的内容写入管道缓冲区中。
非常令人沮丧的是它不会循环并且继续以常规方式写入。您不必进行复制就不必进行大量的vmsplice调用,并且不必为部分vmsplice写入实现循环。
2-我正在从mmaped区域进行vmsplicing,并且能够在vmsplicing之后立即进行munmap操作,而没有崩溃或数据损坏。