在没有文件支持的情况下保留共享内存 (Linux/Windows) (boost::interprocess)
如何在没有文件支持的情况下保留和分配共享内存?我正在尝试保留一大块(数十 GiB)共享内存,并将其作为 IPC 的形式在多个进程中使用。然而,这个块的大部分根本不会被触及(访问将非常稀疏;在进程的整个生命周期中可能只有几百兆字节)并且当应用程序结束时我不关心数据。
因此,执行此操作的方法最好应具有以下属性:
- 不提交整个范围。我将选择要提交的部分(实际使用)。(但模式是相当不可预测的。)
- 不需要内存映射文件或类似的东西。我不需要保留数据。
- 让我从多个进程访问内存区域(我将显式处理锁定。)
- 可在 Linux 和 Windows 中工作(显然需要 64 位操作系统)。
- 实际上使用共享内存。我需要表演。
- (新)操作系统或库不会尝试初始化保留区域(为零或其他值)。这显然是不切实际且不必要的。
我一直在尝试使用 boost::interprocess::shared_memory_object ,但这会导致在文件系统上创建一个大文件(与我的映射内存区域大小相同)。之后它确实会删除该文件,但这几乎没有帮助。
任何帮助/建议/指示/参考都值得赞赏。
PS 我确实知道如何使用本机 API 在 Windows 上执行此操作。 POSIX 似乎具有相同的功能(只是界面更简洁!)我在这里寻找一种跨平台的方式。
更新:我做了一些挖掘,结果发现我认为 Windows 中存在的支持只是内存映射文件的一种特殊情况,使用系统页面文件作为支持。 (我以前从未注意到这一点,因为我在过去的项目中最多使用了几兆字节的共享内存。)
另外,我现在有一个新的需求(上面的数字 6。)
How can I reserve and allocate shared memory without the backing of a file? I'm trying to reserve a large (many tens of GiBs) chunk of shared memory and use it in multiple processes as a form of IPC. However, most of this chunk won't be touched at all (the access will be really sparse; maybe a few hundred megabytes throughout the life of the processes) and I don't care about the data when the applications end.
So preferably, the method to do this should have the following properties:
- Doesn't commit the whole range. I will choose which parts to commit (actually use.) (But the pattern is quite unpredictable.)
- Doesn't need a memory-mapped file or anything like that. I don't need to preserve the data.
- Lets me access the memory area from multiple processes (I'll handle the locking explicitly.)
- Works in both Linux and Windows (obviously a 64-bit OS is needed.)
- Actually uses shared memory. I need the performance.
- (NEW) The OS or the library doesn't try to initialize the reserved region (to zero or whatever.) This is obviously impractical and unnecessary.
I've been experimenting with boost::interprocess::shared_memory_object, but that causes a large file to be created on the filesystem (with the same size as my mapped memory region.) It does remove the file afterwards, but that hardly helps.
Any help/advice/pointers/reference is appreciated.
P.S. I do know how to do this on Windows using the native API. And POSIX seems to have the same functionality (only with a cleaner interface!) I'm looking for a cross-platform way here.
UPDATE: I did a bit of digging, and it turns out that the support that I thought existed in Windows was only a special case of memory-mapped files, using the system page file as a backing. (I'd never noticed it before because I had used at most a few megabytes of shared memory in the past projects.)
Also, I have a new requirement now (the number 6 above.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在 Windows 上,所有内存都必须以某种方式由磁盘支持。
我认为您可以在 Windows 上完成的最接近的操作是内存映射稀疏文件。我认为这适用于您的情况,原因有两个:
我意识到这在技术上不满足您的第二个要求,但不幸的是,我认为这在 Windows 上是不可能的。至少使用这种方法,只有您实际使用的区域才会占用空间。 (并且仅当 Windows 决定将内存提交到磁盘时,它可以自行决定是否执行此操作。)
至于将其转变为跨平台解决方案,一种选择是修改 boost::interprocess 以便它创建Windows 上的稀疏文件。我相信 boost::interprocess 已经满足您对 Linux 的要求,其中 POSIX 共享内存可用。
On Windows, all memory has to be backed by the disk one way or another.
The closest I think you can accomplish on windows would be to memory map a sparse file. I think this will work in your case for two reasons:
I realize that this technically doesn't meet your 2nd requirement, but, unfortunately, I don't think that is possible on Windows. At least with this approach, only the regions you actually use will take up space. (And only when Windows decides to commit the memory to disk, which it may or may not do at its discretion.)
As for turning this into a cross-platform solution, one option would be to modify boost::interprocess so that it creates sparse files on Windows. I believe boost::interprocess already meets your requirements on Linux, where POSIX shared memory is available.