如果在 Windows 上使用 boost managed_shared_memory 则崩溃

Posted

技术标签:

【中文标题】如果在 Windows 上使用 boost managed_shared_memory 则崩溃【英文标题】:Crash if boost managed_shared_memory is used on Windows 【发布时间】:2015-09-25 11:31:41 【问题描述】:

我是新手。 我在以下示例中使用了“提升托管共享内存”,但是在下一行的共享段中分配内存时,一个实例崩溃了:

char_string  key_object(keyHashStr.c_str(), alloc_inst3);

仅当我的示例应用程序的多个实例同时运行时才会发生崩溃。 如果我使用“boost managed windows shared memory”那么就不会崩溃。

有人可以告诉我我做错了什么吗?

    #include <boost/interprocess/sync/interprocess_mutex.hpp>
    #include <boost/interprocess/sync/scoped_lock.hpp>
    #include <boost/interprocess/managed_shared_memory.hpp>
    #include <boost/interprocess/shared_memory_object.hpp>
    #include <boost/interprocess/allocators/allocator.hpp>
    #include <boost/interprocess/containers/flat_map.hpp>
    #include <boost/interprocess/containers/set.hpp>
    #include <boost/interprocess/containers/string.hpp>
    #include <string>
    #include <Windows.h>
    #include <iostream>

    #define AMMSRCUNITLIMIT 0x0100000 /* 1M bytes */
    #define RESERVED_BUFFER_SIZE_WRITE (8 * AMMSRCUNITLIMIT)
    #define SHM_SIZE_FOR_TRACKING 65536
    #define MAX_PATH 260

    using namespace boost::interprocess;

    //Typedefs of allocators and containers
    typedef allocator<void, managed_shared_memory::segment_manager>      void_allocator;
    typedef allocator<char, managed_shared_memory::segment_manager>      char_allocator;
    typedef boost::interprocess::basic_string<char, std::char_traits<char>, char_allocator>   char_string;

    int main(int argc, char *argv[])
    
           managed_shared_memory *m_sharedMemUsage = NULL;
           string keyHashStr;

           try
           
                  m_sharedMemUsage = new  managed_shared_memory(create_only, "MyBookkeeper", 2 * RESERVED_BUFFER_SIZE_WRITE);
                  keyHashStr = "AAAAAAAAAAAAAAAAAAAAAAA";
           
           catch (...)
           
                  while (true)
                  
                         try
                               m_sharedMemUsage = new managed_shared_memory(open_only, "MyBookkeeper");
                               break;
                         
                         catch (...)
                         
                               std::cout << "Some problem, trying again" << std::endl;
                         
                  
                  keyHashStr = "AAAAAAAAAAAAAAAAAAAAAAB";
           

           
                  char_allocator alloc_inst3 = m_sharedMemUsage->get_segment_manager()->get_allocator<char>();
                  int count = 0;
                  while (count < 100000)
                  
                         char_string  key_object(keyHashStr.c_str(), alloc_inst3);
                         ++count;
                  
           
    

【问题讨论】:

定义crash。它会抛出异常吗?进程会死吗? 如果抛出异常可能是有原因的,一遍又一遍地尝试同样的事情不会有太大帮助。 “精神错乱的定义是重复同样的事情,但期待不同的结果”。而是尝试了解为什么抛出异常,以及可以采取哪些措施来防止它。 @MarkJansen :崩溃是指进程正在死亡 好吧,如果它失败一次,你会不断创建新对象的无限循环肯定无济于事...... 【参考方案1】:

我也有类似的问题。该过程在boost内部崩溃。在我的情况下,当两个进程试图同时创建或打开一个特定的共享内存区域时,其中一个进程随后在“for”循环中崩溃。 我在创建共享内存区域时使用了“boost named mutex”。这对我有用。如果我们采用sehe的代码,那么我认为以下修改可以解决问题。

#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/containers/string.hpp>
#include <boost/interprocess/sync/named_mutex.hpp>
#include <string>
#include <iostream>

#define RESERVED_BUFFER_SIZE_WRITE (8 * 0x0100000)

namespace bip = boost::interprocess;

//Typedefs of allocators and containers
typedef bip::allocator<char, bip::managed_shared_memory::segment_manager> char_allocator;
typedef bip::basic_string<char, std::char_traits<char>, char_allocator>   char_string;


int main()

    boost::interprocess::named_mutex MyBookkeeperMutex(boost::interprocess::open_or_create, "MyBookkeeperMutex");

    MyBookkeeperMutex.lock();
    bip::managed_shared_memory m_sharedMemUsage(bip::open_or_create, "MyBookkeeper", 2 * RESERVED_BUFFER_SIZE_WRITE);
    MyBookkeeperMutex.unlock();

    char_allocator alloc_inst3(m_sharedMemUsage.get_segment_manager());
    for (int count = 0; count < 100000; ++count) 
        char_string key_obect("AAAAAAAAAAAAAAAAAAAAAAA", alloc_inst3);
    
    boost::interprocess::named_mutex::remove("MyBookkeeperMutex");

【讨论】:

@rban 见meta.stackexchange.com/questions/5234/…【参考方案2】:

我建议改用open_or_create 标志。

#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/containers/string.hpp>
#include <string>
#include <iostream>

#define RESERVED_BUFFER_SIZE_WRITE (8 * 0x0100000)

namespace bip = boost::interprocess;

//Typedefs of allocators and containers
typedef bip::allocator<char, bip::managed_shared_memory::segment_manager> char_allocator;
typedef bip::basic_string<char, std::char_traits<char>, char_allocator>   char_string;

int main()

    bip::managed_shared_memory m_sharedMemUsage(bip::open_or_create, "MyBookkeeper", 2 * RESERVED_BUFFER_SIZE_WRITE);

    char_allocator alloc_inst3(m_sharedMemUsage.get_segment_manager());
    for (int count = 0; count < 100000; ++count) 
        char_string key_obect("AAAAAAAAAAAAAAAAAAAAAAA", alloc_inst3);
    

注意这不会泄漏资源,因为类的析构函数实际上运行...

【讨论】:

尝试使用 open_or_create 但进程仍然崩溃。

以上是关于如果在 Windows 上使用 boost managed_shared_memory 则崩溃的主要内容,如果未能解决你的问题,请参考以下文章

Boost Zlib的解压缩在Windows上崩溃

在 Windows 上使用 Boost.Asio 的半并发 ICMP ping

在 Mac 和 Windows 上部署 Qt+Boost 应用程序

Windows 上的 Boost::process - 使用 MinGW?

如何使用 Visual Studio 2010 在 Windows 上使用 Open MPI 构建 boost::mpi 库

在 Windows 下使用 SCons 构建 boost::python 模块