提升进程间共享内存删除对象而无需销毁 [英] Boost interprocess shared memory delete object without destroy

查看:199
本文介绍了提升进程间共享内存删除对象而无需销毁的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Windows上有一个增强的进程间Managed_shared_memory,并且在其中存储了一个增强的进程间向量.向量是通过以下方式创建或打开的:

auto* vec = shm.find_or_construct< MyVector >( "Data" )( shmAllocator );

如boost进程间示例中所述.我的观点是,我现在构造或打开了一个对象vec,该对象引用共享内存中的对象.我检查了仅在使用shm.destroy<MyVector>("Data")时调用了vec的d'tor,并且如果我调用delete vec则调用了应用程序崩溃.

现在如何在不破坏基础数据的情况下正确释放对象"vec"? 完整方案:

  • 两个用户正在运行我的软件,它们通过共享内存(在使用文件模拟的Windows中)共享数据
  • 一个用户退出该软件,如果我不致电destroy,则发生内存泄漏,如果我确实按照boost docs中所述致电该软件:

在Windows操作系统中,当前版本支持UNIX取消链接行为的通常可接受的仿真:使用随机名称重命名该文件,并标记为在最后一个打开的句柄关闭时将其删除

  • 其他用户启动了该软件,并尝试共享内存,但是由于文件已重命名,因此无法与我的软件的其他正在运行的实例共享内存.

解决方案

创建或打开矢量的方式

这有点混淆了概念.将其向上查找,并在必要时进行构建. (open_or_create适用于实际的可共享对象,例如内存映射或共享内存对象.)

我检查了仅在使用shm.destroy<MyVector>("Data")时调用了vec的d'tor,如果我调用delete vec,则应用程序崩溃了.

这都是设计使然.

一个用户退出该软件,如果我不打电话给破坏我有内存泄漏,

并非如此.如果不销毁向量,则它仍然存在于托管网段中.这意味着您可以重新打开共享内存段,然后仍然在其中找到它.

要删除共享段,请使用remove()

文档与此相关:

当managed_mapped_file对象被销毁时,该文件将自动取消映射,并且所有资源都将被释放.要从文件系统中删除文件,可以使用标准C std::remove或Boost.Filesystem的remove()函数,但是如果任何进程仍将文件映射到内存中或任何进程打开了文件,则文件删除可能会失败. >

要获得更可移植的行为,请使用f ile_mapping::remove(const char *)操作,该操作将删除文件(即使正在映射文件).但是,如果文件(例如,通过C ++文件流)并且未授予该文件任何删除共享权限,则在某些OS系统中删除将失败.但是在大多数情况下,file_mapping::remove具有足够的可移植性.

此处:

  1. ~basic_managed_mapped_file();

销毁*this并指示使用资源完成了调用过程.析构函数将取消分配系统分配的任何系统资源,以供此进程对此资源使用.仍然可以再次调用open构造函数重载来打开资源.要从系统中擦除资源,请使用remove()

其他信息

如果您真的只是想让向量在最后一个用户释放它之后消失,请使用进程间shared_pointer:

as stated in the boost interprocess examples. My point is that i now constructed or opened an Object vec referencing the object inside the shared memory. I checked that the d'tor of vec is only called when i use shm.destroy<MyVector>("Data") and if i call delete vec the application crashes.

Now how do i properly release the object "vec" without destoying the underlying data? The complete Scenario:

  • Two users are running my software, sharing data via shared memory (in windows emulated using a file)
  • One user exits the software and if i do not call destroy i have a memory leak, if i do call it as stated in the boost docs:

In Windows operating systems, current version supports an usually acceptable emulation of the UNIX unlink behaviour: the file is renamed with a random name and marked as to be deleted when the last open handle is closed

  • Another users starts the software and it tries to share the memory, but as the file has been renamed, it is unable to share the memory with the other running instance of my software.

解决方案

The vector is created or opened by

This is slightly mixing up concepts. It's looked up, and constructed if necessary. (open_or_create applies to actual shareable objects like memory maps or shared memory objects).

I checked that the d'tor of vec is only called when i use shm.destroy<MyVector>("Data") and if i call delete vec the application crashes.

That's both by design.

One user exits the software and if i do not call destroy i have a memory leak,

Not really. If you don't destroy the vector, it still exists in the managed segment. This means that you can reopen the shared memory segment and still find it there.

To remove the shared segment, use remove()

The docs say this related to this:

When the managed_mapped_file object is destroyed, the file is automatically unmapped, and all the resources are freed. To remove the file from the filesystem you could use standard C std::remove or Boost.Filesystem's remove() functions, but file removing might fail if any process still has the file mapped in memory or the file is open by any process.

To obtain a more portable behaviour, use file_mapping::remove(const char *) operation, which will remove the file even if it's being mapped. However, removal will fail in some OS systems if the file (eg. by C++ file streams) and no delete share permission was granted to the file. But in most common cases file_mapping::remove is portable enough.

And here:

  1. ~basic_managed_mapped_file();

Destroys *this and indicates that the calling process is finished using the resource. The destructor function will deallocate any system resources allocated by the system for use by this process for this resource. The resource can still be opened again calling the open constructor overload. To erase the resource from the system use remove()

Additional info

If you really just want the vector gone after the last user releases it, use the interprocess shared_pointer: http://www.boost.org/doc/libs/1_64_0/doc/html/interprocess/interprocess_smart_ptr.html#interprocess.interprocess_smart_ptr.shared_ptr

这篇关于提升进程间共享内存删除对象而无需销毁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆