在最初的vmsplice()
实现中,建议如果您的用户级缓冲区是管道中最大页数的 2 倍,则缓冲区后半部分的成功 vmsplice() 将保证内核已使用缓冲区的前半部分。
但这毕竟不是真的,特别是对于 TCP,内核页面会一直保留到从另一端收到 ACK 为止。解决这个问题留作未来的工作,因此对于 TCP,内核仍然必须从管道复制页面。
vmsplice()
有SPLICE_F_GIFT
处理这个问题的选项,但问题是这暴露了另外两个问题——如何有效地从内核获取新页面,以及如何减少缓存垃圾。第一个问题是 mmap 需要内核清除页面,第二个问题是尽管 mmap 可能会使用内核中花哨的kscrubd功能,但这会增加进程的工作集(缓存垃圾)。
基于此,我有以下问题:
- 通知用户空间安全重用页面的当前状态是什么?我对页面 splice()d 到套接字 (TCP) 上特别感兴趣。在过去的 5 年里发生了什么事情吗?
- /// 是当前在 TCP 服务器
mmap
中进行零复制的最佳实践vmsplice
,还是我们今天有更好的选择splice
?munmap