有很好的理由不允许此功能,特别是从安全方面考虑。"分享这个内存"的API将破坏访问权限系统。
假设一个应用程序在内存中保存了某种关键/敏感信息; 应用程序链接(例如使用共享库、预加载、修改后的链接器/加载程序)到外部组件,这些组件仅仅为了好玩而决定“分享地址空间”。这将是一场自由竞技,一种绕过任何数据访问权限/限制的方法。你会挤入应用程序。
对于您的用例来说并不好,但从系统/应用程序完整性的角度来看是合理的。尝试搜索网页以了解为什么通常不希望进行这种访问(例如:/proc/pid/mem mmap漏洞)。
如果您使用的库旨在允许此类共享访问,则必须自行提供钩子以分配此类共享缓冲区或使用其他地方预分配的(可能共享的)缓冲区。
编辑:要明确这一点,进程边界明确是关于不共享地址空间(以及其他事情)。
如果您需要共享地址空间,请使用线程(那么整个地址空间都是共享的,永远不需要“导出”任何东西),或者显式设置共享内存区域,就像您设置共享文件一样。
从后者的角度来看,两个未以O_EXCL
打开的进程会共享文件的访问权限。但是,如果一个进程已经以O_EXCL
方式打开了它,则“使其共享”的唯一方法(可供另一个进程打开)是首先将其close()
,然后再次open()
它,而不使用O_EXCL
。如果您已经以这种方式打开了一个文件,没有其他方法可以从中删除独占访问权,而只能先关闭它。
正如没有办法除非先取消映射它,否则无法删除被映射为独占访问的内存区域 - 对于进程的内存来说,默认情况下是使用MAP_PRIVATE
,原因充分。
更多信息:一个进程共享的内存缓冲区与进程共享的文件其实并没有太大不同;使用SysV-IPC风格的语义,你可以有:
| SysV IPC共享内存 文件
==============+===================================================================
创建 | id = shmget(key,..., IPC_CREAT); fd = open("name",...,O_CREAT);
查找 | id = shmget(key,...); fd = open("name",...);
访问 | addr = shmat(id,...); addr = mmap(...,fd,...);
|
全局句柄 | IPC key 文件名
本地句柄 | SHM ID号 文件描述符号码
内存位置 | 由shmat()创建 由mmap()创建
也就是说,密钥是您要寻找的“句柄”,以与传递文件名相同的方式传递它,然后IPC连接的两端都可以使用该密钥检查共享资源是否存在,并通过它访问(附加到句柄)内容。
ioctl()
调用来实现此功能,将PID和[start,end]
范围作为参数。您本质上将在/proc/PID/mem
上重新实现mmap()
- 这个函数因安全原因在近十年前从内核中删除,详情请参见http://www.securiteam.com/unixfocus/6V00F206AA.html。虽然这不是不可能实现的,但并不是一个好主意... - FrankH.