hrr*_*hrr 13 c++ boost shared-memory interprocess
我想在几个进程之间使用共享内存,并希望能够继续使用原始指针(和stl容器).
为此,我使用映射在固定地址的共享内存:
segment = new boost::interprocess::managed_shared_memory(
boost::interprocess::open_or_create,
"MySegmentName",
1048576, // alloc size
(void *)0x400000000LL // fixed address
);
Run Code Online (Sandbox Code Playgroud)
选择这个固定地址的好策略是什么?例如,我应该使用一个相当高的数字来减少我用完堆空间的可能性吗?
Jos*_*vin 15
这是一个难题.如果你要求一个程序来创建子项,并且只有父项和子项将使用内存段,请确保在fork之前映射它.子节点将自动从父节点继承映射,无需使用固定地址.
如果不是,那么首先要考虑的是你是否真的需要使用原始STL容器而不是boost进程间容器.您已经使用boost进程来分配共享内存段表明您使用boost时没有任何问题,因此我可以想到使用STL容器的唯一优势是您不必移植现有代码.请记住,为了使用固定地址,容器及其包含的指针(假设您正在使用指针容器)将需要保存在共享内存空间中.
如果您确定这是您想要的,那么您必须找出一些方法来协商地址.请记住,允许操作系统拒绝所需的固定内存地址.如果该地址的页面已经映射到内存或已分配,它将拒绝一个地址.因为不同的程序会在不同的时间分配不同数量的内存,哪些页面可用且哪些页面不可用会因程序而异.
因此,您需要程序在内存地址上达成共识.这意味着可能必须尝试和拒绝几个地址.如果有可能在启动后的某个时候新程序会变得有兴趣,那么寻求共识将不得不重新开始.该算法看起来像这样:
要想出A应该提出的地址,你可以让A映射成一个非固定的内存段,查看它映射到的地址,并提出该地址.如果不满意,请映射另一个细分并提出建议.您需要在某个时刻取消映射段,但是您无法立即取消映射它们,因为如果取消映射然后重新映射相同大小的段,则操作系统将反复给您相同的地址.请记住,您可能永远不会达成共识 ; 并不能保证在所有流程的公共位置都有足够大的段.如果您的程序全部独立使用几乎所有内存,也就是说,如果它们通过大量交换备份(例如,如果您足够关注性能以使用共享内存,希望您避免交换),则可能会发生这种情况.
以上所有假设您处于相对受限的地址空间.如果你是64位,这可能会有效.大多数计算机的RAM +交换将远远小于64位允许的内存,因此您可以将内存映射到一个非常远的固定地址,而所有进程都不可能已映射.我建议至少2 ^ 48,因为目前的64位x86处理器不会超出该范围(尽管指针是64位,你只能插入48位允许的RAM,仍然是一吨写这篇文章的时间).虽然智能堆分配器没有理由不能利用广阔的地址空间来减少其簿记工作,但要真正强大,您仍需要建立共识.请记住,您至少希望地址可以配置 - 即使我们很快就没有那么多内存,从现在开始,然后其他人可能有相同的想法并选择您的地址.
要进行双向通信,您可以使用任何套接字,管道或其他共享内存段.您的操作系统可能提供其他形式的IPC.但强烈认为,如果你刚刚使用了boost进程容器,那么你现在可能会引入比你必须处理的复杂性更多;)
| 归档时间: |
|
| 查看次数: |
3568 次 |
| 最近记录: |