Boost共享内存无法初始化。

3

你好,以下是我的问题:

我正在尝试使用以下代码段创建共享内存段:

      #include <boost/interprocess/managed_shared_memory.hpp>
      using namespace boost::interprocess;

      ...   

      shared_memory_object::remove("MyShareMem");
      try {

        managed_shared_memory segment_(create_only,
                                       "MyShareMem",
                                       10 * 1024 * 1024);
        ...
      }
      catch (interprocess_exception &ex) {
        std::cout << "Exception: "<< ex.what() << std::endl;
      }

但是我遇到了一个异常:

Exception: boost::interprocess::intermodule_singleton初始化失败

我不知道该怎么做和如何解决这个问题。

有没有什么想法来处理这个问题?


更新:

我在这里找到了解决方案boost::interprocess_exception - library_error exception when creating shared_memory_object

这有点奇怪,因为boost依赖于Windows事件记录器。如果没有ID = 6005的事件,它就会抛出异常。

以下是来自boost 1.62.0 win32_api.hpp的代码片段

//Obtains the bootup time from the System Event Log,
//event ID == 6005 (event log started).
//Adapted from http://msdn.microsoft.com/en-us/library/windows/desktop/bb427356.aspx
inline bool get_last_bootup_time(std::string &stamp)
{
   const char *source_name = "System";
   const char *provider_name = "EventLog";
   const unsigned short event_id = 6005u;

解决方法就是添加6005事件,所有工作都恢复正常。

你尝试过分配较小的部分吗? - undefined
是的,我刚刚尝试了1024字节,但仍然不起作用。当然,在重启我的电脑之后问题可能会解决,但我宁愿找到一个更好的解决方案 :) - undefined
异常来自这里intermodule_singleton_common - undefined
我在boost中发现了一个类似的bug [Ticket #12232]{https://svn.boost.org/trac/boost/ticket/12232}。 - undefined
2个回答

2
我在这里找到了一个解释,为什么会使用Windows系统事件记录器。来自Boost文档共享内存仿真文件夹
共享内存(shared_memory_object)在Windows中是使用内存映射文件实现的,放置在共享文档文件夹中的共享目录中(SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\Common AppData)。该目录名称是通过COM调用获取的最后一次启动时间(如果定义了BOOST_INTERPROCESS_BOOTSTAMP_IS_LASTBOOTUPTIME),或者通过搜索系统日志查找启动事件(默认实现),以便每次启动时都会创建一个新的文件夹,从而获得内核持久性共享内存。
如果使用BOOST_INTERPROCESS_BOOTSTAMP_IS_LASTBOOTUPTIME,由于与COM实现相关的错误,在Boost 1.48和Boost 1.49中,启动时间文件夹被删除,并直接在共享文档文件夹中创建文件,恢复到文件系统持久性共享内存。Boost 1.50修复了这些问题并恢复了启动时间目录和内核持久性。
如果您需要重现与使用该版本编译的应用程序通信的Boost 1.48和Boost 1.49行为,请在boost/interprocess/detail/workaround.hpp的Windows配置部分中注释#define BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME指令。
如果使用默认实现(未定义BOOST_INTERPROCESS_BOOTSTAMP_IS_LASTBOOTUPTIME)且未找到启动事件,则可能是由于某些错误的软件导致事件日志泛滥或擦除。
在任何错误情况下(未定义共享文档文件夹或无法获取启动时间),该库都会抛出错误。您仍然可以使用Boost.Interprocess定义自己的目录作为共享目录。只需在使用库时定义BOOST_INTERPROCESS_SHARED_DIR_PATH,该路径将用于放置共享内存文件。
此处还可以找到更好的解决方案。您只需要定义BOOST_INTERPROCESS_SHARED_DIR_PATH,设置您自己的文件夹来存储boost共享内存文件。这样,您就不必依赖于Windows事件日志记录器了。

1

虽然评论有些晚,但还是要说一下

BOOST_INTERPROCESS_SHARED_DIR_PATH会将路径硬编码,这不是最佳实践。更好的方式是定义BOOST_INTERPROCESS_SHARED_DIR_FUNC并实现它。

void get_shared_dir(std::string& shared_dir)
{
    // get dir path from environment variable for instance
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接