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

时间:2019-02-14 18:24:06

标签: c linux shared-memory mmap low-level

我有一个庞大的文件,即1TiB作为'filehandler'拥有,允许rwx ------。我mmap(2)-将其放入64位地址空间,所有工作均成功完成。该文件由以“ filehandler”用户身份运行的进程处理。

其他进程从该处理程序进程中请求服务,该进程以文件处理程序以外的其他用户身份运行。他们通过unix套接字登录到处理程序。他们按照IPC规则进行交流,一切正常。

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

如果共享内存,只是请求的进程允许文件的允许部分,则将获得最佳性能。

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

是否有任何方法仅将mmap(2)-ed空间的允许部分共享给任何像shm技术这样的进程?

2 个答案:

答案 0 :(得分:2)

  

是否有任何方法仅将mmap(2)-ed空间的允许部分共享给任何像shm技术这样的进程?

TL; DR :否。


更详细地

  

如何在shmget之类的内存中重新映射文​​件mmap(2)-

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

现在,返回

  

是否有任何方法仅将mmap(2)-ed空间的允许部分共享给任何像shm技术这样的进程?

请注意,在以上两种情况下,都是要映射的对象(共享内存段)提供无关进程之间的共享,而与mmap()本身无关。当mmap()映射任何其他类型的对象(例如常规文件)时,也是如此。它始终是映射的对象,通过它可以协调任何共享访问。之所以必须这样,是因为内存映射是一个进程的属性-它本身不是可共享的。

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

答案 1 :(得分:1)

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

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

所有这些资源(无论是SysV还是BSD)都具有一组与之相关的权限位,这些权限位可以使它们具有一定的安全性,但是对于文件来说,只是以全局(整个资源)方式使用,您可以访问全部内容或根本不访问任何内容。

顺便说一句,您可以通过将段内容复制到不同的私有段(仅希望客户端看到的大小)来实现所需的内容,这样您就可以可以更好地控制允许客户进行的操作和对象。

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

从我的角度来看,您使事情有些复杂,但是您比我更了解您的应用程序是如何设计的。