Unix:在进程之间共享已映射的内存

前端之家收集整理的这篇文章主要介绍了Unix:在进程之间共享已映射的内存前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个预建的用户空间库,具有一个API
void getBuffer (void **ppBuf,unsigned long *pSize);
void bufferFilled (void *pBuf,unsigned long size);

这个想法是我的代码从lib请求一个缓冲区,填充它的东西,然后把它移回到lib.

我想要另一个进程能够填充这个缓冲区.我可以通过使用shm * / shm_ * API创建一些新的共享缓冲区来完成此操作,另一个进程填充,然后将其复制到lib本地进程中的lib缓冲区中,但这具有额外的(潜在的大量)复制.

有没有办法共享一个进程映射的ALREADY的内存?例如:

[local lib process]
getBuffer (&myLocalBuf,&mySize);
shmName = shareThisMemory (myLocalBuf,mySize);

[other process]
myLocalBuf = openTheSharedMemory (shmName);

这样,其他进程可以直接写入lib的缓冲区.
(进程之间的同步已经被照顾,所以没有问题).

没有很好的理由不允许这个功能,特别是从安全方面的事情. “共享这个mem”API会颠覆访问权限系统.

假设应用程序在内存中保存某种关键/敏感信息;应用程序链接(通过例如使用共享库,预加载,修改链接器/加载器)到外部的任何组件,并且所述组件对于它的纯粹乐趣决定“共享地址空间”.这将是一种免费的方式来绕过任何数据访问权限/限制.你会把你的方式通入应用程序.

不适合您的用户体验,承认,但从系统/应用程序完整性的角度来说是合理的.尝试在网络上搜索/ proc / pid / mem mmap漏洞,以了解为什么不需要这种访问(一般来说).

如果您使用的库旨在允许这种共享访问,则它必须自己提供钩子来分配这样的共享缓冲区,或者使用其他地方预先分配(可能共享的)缓冲区.

编辑:为了清楚这一点,流程边界显然是不共享地址空间(除其他外).
如果您需要共享地址空间,请使用线程(然后整个地址空间是共享的,并且从不需要“导出”任何内容),或者以与设置一个共享内存区域相同的方式明确设置共享内存区域共享文件.

从后一种观点来看,两个进程不打开它O_EXCL将共享对文件的访问.但是,如果一个进程已经打开O_EXCL,那么“使其共享”(对另一个进程可以打开)的唯一方法是先关闭()它,然后再打开()它,而不用O_EXCL.没有其他方式可以从您打开的文件中“删除”独占访问权限,而不是先关闭它们.
正如没有办法删除对映射的内存区域的独占访问,除了首先取消映射以外,对于进程的内存,MAP_PRIVATE是默认的,这是出于好的原因.

更多:进程共享内存缓冲区的确与进程共享文件没有太大的不同;使用SysV-IPC风格的语义,你有:

              | SysV IPC shared memory            Files
==============+===================================================================
creation      | id = shmget(key,...,IPC_CREAT);  fd = open("name",O_CREAT);
lookup        | id = shmget(key,...);             fd = open("name",...);
access        | addr = shmat(id,...);             addr = mmap(...,fd,...);
              |
global handle | IPC key                           filename
local handle  | SHM ID number                     filedescriptor number
mem location  | created by shmat()                created by mmap()

即关键是您正在寻找的“句柄”,通过与传递文件名相同的方式,IPC连接的两边可以使用该键来检查共享资源是否存在,以及访问(附加)到处理)内容虽然如此.

猜你在找的Bash相关文章