是否可以并且是否明智使用sendfile()
(或其Darwin/BSD衍生版本fcopyfile()
)在共享内存对象和文件之间直接传输数据?
sendfile()
和fcopyfile()
等函数可以完全在内核空间中执行所有机械必需品,从而实现这种数据传输-当调用这些函数时,您将传递两个打开描述符,一个源和一个目标,它们会从那里接管。
其他复制数据的方法无论如何都需要手动穿越内核空间和用户空间之间的边界。这种上下文切换从性能上来说本质上相当昂贵。
我找不到关于像这样使用共享内存描述符作为参数的确切信息:没有支持或反对这种做法的文章;在各自的man
页面中也没有发现任何相关内容;没有公开考虑将sendfile()
用于共享内存描述符的Twitter推文以及其他……但是,我认为我应该能够做到这一点:
char const* name = "/yo-dogg-i-heard-you-like-shm"; /// only one slash, at zero-index
int len = A_REASONABLE_POWER_OF_TWO; /// valid per shm_open()
int descriptor = shm_open(name, O_RDWR | O_CREAT, 0600);
int destination = open("/tmp/yodogg.block", O_RDWR | O_CREAT, 0644);
void* memory = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, descriptor, 0);
off_t bytescopied = 0;
sendfile(destination, descriptor, &bytescopied, len);
/// --> insert other stuff with memset(…), memcopy(…) &c. here, possibly
munmap(memory, len);
close(descriptor); close(destination);
shm_unlink(name);
这是错误的方法还是有效的技术?
如果是后者,是否可以在复制数据之前调整内存共享映射的大小?
编辑:我正在 macOS 10.12.4 上开发与此查询相关的项目;我旨在使其在 Linux 上工作,并最终实现 FreeBSD 的互操作性。
shm_open()
、mmap(…, MAP_SHARED, …)
和sendfile()
的三连击——有两个原因。首先,一个小问题:我现在正在macOS上本地开发,所以我的sendfile()
是使用fcopyfile()
的polyfill...第二:我的当前任务是通过其包装类实现对可写文件映射内存的访问(该包装器已经提供只读内存映射,请参见https://github.com/fish2000/libimread/blob/master/src/file.cpp#L115-L140);我将利用我在这方面学到的知识以及从SO上获得的知识来解决共享内存问题。 - fish2000