C++ c++;Boost进程间共享\u ptr异常

C++ c++;Boost进程间共享\u ptr异常,c++,shared-ptr,unordered-map,boost-interprocess,C++,Shared Ptr,Unordered Map,Boost Interprocess,我试图将进程间无序映射中的共享指针(boostinterprocess)保存为值。在我的测试程序中,我插入了大约100个元素。每个元素都有一个字符串作为键,一个共享的ptr作为值。共享_ptr是指向复杂数据类型的指针 第一个元素的创建和插入已成功完成。但是,当我为第二个元素创建共享的_ptr实例时,会出现一个异常。我得到以下例外情况: 错误:boost::进程间异常::库错误。 错误代码:错误的文件描述符。 本机错误:0 我已将代码粘贴到下面。感谢您的帮助。谢谢 defs.h // basic

我试图将进程间无序映射中的共享指针(boostinterprocess)保存为值。在我的测试程序中,我插入了大约100个元素。每个元素都有一个字符串作为键,一个共享的ptr作为值。共享_ptr是指向复杂数据类型的指针

第一个元素的创建和插入已成功完成。但是,当我为第二个元素创建共享的_ptr实例时,会出现一个异常。我得到以下例外情况:

错误:boost::进程间异常::库错误。 错误代码:错误的文件描述符。 本机错误:0

我已将代码粘贴到下面。感谢您的帮助。谢谢

defs.h

// basic shared memory defs.
#pragma once

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

namespace bip = boost::interprocess;

namespace ip {

namespace shmem {

  using segment = bip::managed_shared_memory;
  using segment_manager = segment::segment_manager;

  using void_allocator = bip::allocator<void, segment_manager>;
  using char_allocator = bip::allocator<char, segment_manager>;
  using int_allocator = bip::allocator<int, segment_manager>;
  using double_allocator = bip::allocator<double, segment_manager>;
  using size_t_allocator = bip::allocator<size_t, segment_manager>;
  using string = bip::basic_string<char, std::char_traits<char>, char_allocator>;

} // namespace shmem

} // namespace ip
//基本共享内存定义。
#布拉格语一次
#包括
#包括
#包括
名称空间bip=boost::进程间;
命名空间ip{
名称空间shmem{
使用段=bip::托管共享内存;
使用段\管理器=段::段\管理器;
使用void_分配器=bip::分配器;
使用char_分配器=bip::分配器;
使用int_分配器=bip::分配器;
使用双_分配器=bip::分配器;
使用size\u t\u allocator=bip::allocator;
使用string=bip::basic_string;
}//名称空间shmem
}//名称空间ip
映射值.h

#pragma once
#include <boost/interprocess/smart_ptr/deleter.hpp>
#include <boost/interprocess/smart_ptr/shared_ptr.hpp>
#include <cassert>

#include "defs.h"

namespace ip
{

template <typename ValueType>
class MapValue
{
public:
  using MVType = MapValue<ValueType>;
  typedef typename bip::deleter<MVType, shmem::segment_manager> MVDeleter;
  typedef typename bip::managed_shared_ptr<MVType, shmem::segment>::type MapValuePtr;

  MapValue(const shmem::void_allocator&, ValueType value=ValueType(), size_t=0);

  MapValue(const MapValue& other);
  MapValue& operator=(const MapValue& other);
  MapValue(const MapValue&& other) noexcept;
  MapValue& operator=(const MapValue&& other) noexcept;
  void swap(const MapValue& other) noexcept;

  size_t GetTimestamp() const { return mTimestamp; }
  ValueType GetValue() const { return mValue; }

private:
  size_t mTimestamp;
  ValueType mValue;
};

} // namespace ip
#pragma一次
#包括
#包括
#包括
#包括“defs.h”
命名空间ip
{
模板
类映射值
{
公众:
使用MVType=MapValue;
typedef typename bip::deleter MVDeleter;
typedef typename bip::managed_shared_ptr::type MapValuePtr;
MapValue(const shmem::void_分配器&,ValueType value=ValueType(),size_t=0);
MapValue(常量MapValue和其他);
MapValue和运算符=(常量MapValue和其他);
MapValue(常量MapValue&&other)无例外;
MapValue和运算符=(常量MapValue和其他)无异常;
无效交换(常量映射值和其他)无例外;
大小\u t GetTimestamp()常量{return mTimestamp;}
ValueType GetValue()常量{return mValue;}
私人:
尺寸和时间戳;
价值型价值;
};
}//名称空间ip
map-value.cc

#include "map-value.h"

namespace ip
{

template <typename ValueType>
MapValue<ValueType>::MapValue(const shmem::void_allocator &void_allocator
                                          , ValueType value, size_t expire_ts)
: mTimestamp(expire_ts)
, mValue(value, void_allocator)
{
}

template <typename ValueType>
MapValue<ValueType>::MapValue(const MapValue& other)
: mTimestamp(other.mTimestamp)
, mValue(other.mValue)
{
}

template <typename ValueType>
MapValue<ValueType>&
MapValue<ValueType>::operator=(const MapValue& other)
{
  MapValue tmp(other);
  swap(tmp);
  return *this;
}

template <typename ValueType>
MapValue<ValueType>::MapValue(const MapValue&& other) noexcept
: mTimestamp(std::move(other.mTimestamp))
, mValue(std::move(other.mValue))
{
}

template <typename ValueType>
MapValue<ValueType>&
MapValue<ValueType>::operator=(const MapValue&& other) noexcept
{
  auto tmp = std::move(other);
  swap(tmp);
  return *this;
}

template <typename ValueType>
void
MapValue<ValueType>::swap(const MapValue& other) noexcept
{
  mTimestamp = other.mTimestamp;
  mValue = other.mValue;
}

template class MapValue<shmem::string>;

} // namespace ip
#包括“map value.h”
命名空间ip
{
模板
MapValue::MapValue(常量shmem::void\u分配器和void\u分配器
,值类型值,大小(过期)
:mTimestamp(过期)
,mValue(值,void\u分配器)
{
}
模板
MapValue::MapValue(常量MapValue和其他)
:mTimestamp(其他.mTimestamp)
,mValue(其他.mValue)
{
}
模板
映射值&
MapValue::operator=(常量MapValue和其他)
{
MapValue tmp(其他);
掉期(tmp);
归还*这个;
}
模板
MapValue::MapValue(常量MapValue&&other)无例外
:mTimestamp(std::move(other.mTimestamp))
,mValue(std::move(other.mValue))
{
}
模板
映射值&
MapValue::operator=(常量MapValue&&other)noexcept
{
自动tmp=标准::移动(其他);
掉期(tmp);
归还*这个;
}
模板
无效的
MapValue::swap(常量MapValue和其他)无例外
{
mTimestamp=其他.mTimestamp;
mValue=其他.mValue;
}
模板类映射值;
}//名称空间ip
无序映射主控.cc

#include <chrono>
#include <cstdlib>
#include <iostream>
#include <functional>                 //std::equal_to
#include <sstream>
#include <string.h>

#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/unordered_map.hpp>    //boost::unordered_map
#include <boost/functional/hash.hpp>  //boost::hash

#include "map-value.h"

using namespace boost::interprocess;
using namespace ip;

int
main ()
{
  shared_memory_object::remove("MySharedMemory");

  // Create shared memory
  managed_shared_memory segment(create_only, "MySharedMemory", 1024*64);

  // Note that unordered_map<Key, MappedType>'s value_type is 
  // std::pair<const Key, MappedType>, so the allocator must allocate a pair.
  // 
  typedef int  KeyType;
  //typedef size_t  MappedType;
  typedef std::pair<const int, MapValue<shmem::string>::MapValuePtr> ValueType;

  // Typedef the allocator
  typedef allocator<ValueType, shmem::segment_manager> ShmemAllocator;

  // Alias an unordered_map of ints that uses the previous STL-like allocator.
  typedef boost::unordered_map<KeyType, MapValue<shmem::string>::MapValuePtr
                               , boost::hash<KeyType>, std::equal_to<KeyType>
                               , ShmemAllocator> SharedHashMap;

  // Construct a shared memory hash map.
  // Note that the first parameter is the initial bucket count and
  // after that, the hash function, the equality function and the allocator
  SharedHashMap *hashmap = segment.construct<SharedHashMap>("SharedHashMap")      //object name
                               (4                                       // bucket count
                                , boost::hash<KeyType>()                // hash func
                                , std::equal_to<KeyType>()              // equality func
                                , segment.get_allocator<ValueType>());  //allocator instance

  int i;
  std::string test("test");

  using MVString = MapValue<shmem::string>;
  using MVStringPtr = MVString::MapValuePtr;
  using MVStringDeleter = MVString::MVDeleter;
  shmem::void_allocator alloc_inst (segment.get_segment_manager());

  try {
    // Insert data in the hash map
    for (i = 0; i < 100; ++i) {
      // Create a shared pointer in shared memory
      // pointing to a newly created object in the segment
      std::ostringstream ostr;
      ostr << test << i;
      const uint64_t now = std::chrono::duration_cast<std::chrono::microseconds>(
                                  std::chrono::steady_clock::now().time_since_epoch()).count();
      size_t ts = now + 60*1000000;   // 60s from now.

      shmem::string name(ostr.str().c_str(), alloc_inst);
      std::cout << "created name: " << name << '\n';
      MVStringPtr sh_ptr_instance =
          make_managed_shared_ptr(segment.construct<MVString>("MVString")(alloc_inst
                                                                          , name, ts), segment);

      assert(sh_ptr_instance.use_count() == 1);
      std::cout << "created shared_ptr" << '\n';

      hashmap->insert(ValueType(i, sh_ptr_instance));
      std::cout << "Inserting at " << i << ": "
                << "value: " << ostr.str() << ". "
                << "timestamp: " << ts << '\n';
    }
  }
  catch (const bip::interprocess_exception& e) {
    std::cout << "error: " << e.what() << ". "
              << "error-code: " << strerror(e.get_error_code()) << ". "
              << "error-msg: " << e.get_native_error() << ". " << '\n';
    std::cout << "Error while inserting element #" << (i+1) << '\n';
    shared_memory_object::remove("MySharedMemory");
    std::exit(-1);
  }

  std::cout << i << " values inserted into shared memory" << '\n';
  return 0;
}
#包括
#包括
#包括
#包括//标准::等于
#包括
#包括
#包括
#包括
#include//boost::无序映射
#include//boost::hash
#包括“映射值.h”
使用名称空间boost::interprocess;
使用名称空间ip;
int
主要()
{
共享内存对象::删除(“MySharedMemory”);
//创建共享内存
托管共享内存段(仅创建“MySharedMemory”,1024*64);
//请注意,无序_映射的值_类型为
//std::pair,因此分配器必须分配一对。
// 
typedef int-keype;
//typedef size_t MappedType;
typedef std::pair ValueType;
//在分配器中键入def
typedef分配器ShmemAllocator;
//别名使用以前类似STL的分配器的无序整数映射。
typedef boost::无序的_映射SharedHashMap;
//构造共享内存哈希映射。
//请注意,第一个参数是初始桶计数和
//然后是散列函数、相等函数和分配器
SharedHashMap*hashmap=segment.construct(“SharedHashMap”)//对象名
(4//桶计数
,boost::hash()//hash func
,std::equal_to()//equality func
,segment.get_分配器();//分配器实例
int i;
标准:字符串测试(“测试”);
使用MVString=MapValue;
使用MVStringPtr=MVString::MapValuePtr;
使用MVStringDeleter=MVString::MVDeleter;
shmem::void_分配器alloc_inst(segment.get_segment_manager());
试一试{
//在哈希映射中插入数据
对于(i=0;i<100;++i){
//在共享内存中创建共享指针
//指向段中新创建的对象
标准:ostringstream ostr;

ostr我自己已经找到了答案。看起来给共享指针的名称字符串必须是唯一的

MVStringPtr sh_ptr_instance =
       make_managed_shared_ptr(segment.construct<MVString>("MVString")(alloc_inst, name, ts), segment);
MVStringPtr sh_ptr_实例=
使受管共享(段结构(“MVString”)(alloc_inst,name,ts),段);

例如,字符串“MVString”在上面的代码中,代码必须是唯一的。我看到了错误,因为我正在使用相同的名称创建多个共享指针。使名称字符串唯一解决了我的问题。

请提供一个。不确定完整示例的含义。我已提供了所需的完整代码。请将每个代码块保存到单独的文件中(我甚至提供了文件名)。之后,您可以执行以下操作:g++-std=c++1y-o umap\u master map-value.cc无序的\u map\u master.cc;g++-std=c++1y-o umap\u slave map-value.cc无序的\u map\u slave.cc;您可以运行“umap\u master”,您会看到错误。不确定您为什么会被否决?如果您需要更多信息,不能要求更多信息而不进行否决?我相信您的示例是indeed完整且可验证。第一个词是关键字:Minimal。这意味着您必须提供一小块
MVStringPtr sh_ptr_instance =
       make_managed_shared_ptr(segment.construct<MVString>("MVString")(alloc_inst, name, ts), segment);