c语言 - 如何像 shmget 一样在内存中重新映射文件 mmap(2)-ed



我有一个大文件,即 1TiB 作为"文件处理程序"拥有,允许 rwx------.我 mmap(2) - 将其放入 64 位地址空间, 一切工作顺利.此文件由以用户"文件处理程序"身份运行的进程处理。

其他进程从以文件处理程序以外的其他用户身份运行的此处理程序进程请求服务。他们通过 unix 套接字登录到处理程序。他们通过IPC规则进行沟通,一切都很好。

出于安全原因,不得将整个文件共享给请求者。在文件中,仅允许请求者进程访问某些部分。

如果共享内存,则提供最佳性能,仅使用请求进程的文件允许部分。

例如,shm 提供了访问其他进程段的密钥,它是针对请求者的实用目标。

有没有办法只将 mmap(2) 空间中允许的部分共享给任何标识为像 shm 技术这样的进程?

有没有办法只将 mmap(2)-ed 空间中允许的部分共享给任何标识为像 shm 技术这样的进程?

TL;唐:没有。


更详细地说,

如何在内存中重新映射文件 mmap(2)-ed 像 shmget

mmap()shmget()并没有真正的可比性。 更好的比较是一方面是shm_open()/ftruncate()/mmap()的组合,另一方面是shmget()/shmat()的组合。 这些是 POSIX 中用于创建标记的共享内存段并将其映射到进程的地址空间的主要替代方法。 你应该认识到shmget()的类比是shm_open()的,而在这种情况下mmap()的类比是shmat()

现在,回到

有没有办法只将 mmap(2) 空间中允许的部分共享给任何标识为像 shm 技术这样的进程?

请注意,在上述两种情况下,都是被映射的对象(共享内存段)提供不相关进程之间的共享,与mmap()本身无关。 这同样适用于mmap()映射任何其他类型的对象,例如常规文件。 它始终是映射的对象,通过该对象调解任何共享访问。 它必须是这样的,因为内存映射是一个进程的属性 - 它本身不是可共享的。

您的设计要求文件处理程序进程充当数据的看门人,而不是允许客户端直接访问数据。 这很好,但它会阻止客户端将文件映射到内存。 您可以安排客户端通过任一类型的共享内存段访问数据,但这需要服务器将正确的数据从大文件中复制到客户端的共享内存段中。 这可能确实是需要考虑的事情,但您可以忘记服务器为客户端提供对文件的直接内存映射访问。

shmget

系统调用(System V AT&T派生实现)和mmap(伯克利BSD系统派生实现)的实现之间没有联系 的确,在BSD系统中,AT&T共享内存是通过使用没有附加文件的mmap私有段来实现的,但这也是没有用的, 因为您需要将共享段与文件关联。

根据需要,共享与文件内容相关的内存段的唯一可能性是使用mmap系统调用,因为系统 V 共享内存段无法将文件与它们关联。

所有这些资源(SysV 或 BSD)都有一组与它们关联的权限位,允许它们以一定的安全性使用,但就像文件一样,只能以全局(整个资源)方式使用,使您能够访问整个事物或根本不访问。

顺便说一句,您可以通过将段内容复制到不同的私有段(仅您希望客户端被允许查看的大小)来实现您想要的内容,仅允许它访问的段,这样您就可以更好地控制允许客户端执行的操作和内容。

最后,请记住,此方法需要复制共享内存段,因此,如果您不希望客户端所做的修改在客户端完成使用时丢失,则需要记住为客户复制回导出的段。

从我的角度来看,你把事情复杂化了一点,但你比我更了解你的应用程序是如何设计的。

最新更新