【问题标题】:Map in Shared memory共享内存中的映射
【发布时间】:2023-04-06 18:03:02
【问题描述】:

我正在尝试在共享内存中创建一个 unordered_map。我正在使用分配器来实现目的。

代码

void *addr;
void *pool;
int shmid;

template<class T>
class MyPoolAlloc {
private:
public:
    typedef size_t     size_type;
    typedef ptrdiff_t  difference_type;
    typedef T*         pointer;
    typedef const T*   const_pointer;
    typedef T&         reference;
    typedef const T&   const_reference;
    typedef T          value_type;

   template<class X>
   struct rebind
   { typedef MyPoolAlloc<X> other; };

   MyPoolAlloc() throw() {
   }
   MyPoolAlloc(const MyPoolAlloc&) throw()  {
   }

   template<class X>
   MyPoolAlloc(const MyPoolAlloc<X>&) throw() {
   }

   ~MyPoolAlloc() throw() {
   }

  pointer address(reference __x) const { return &__x; }

  const_pointer address(const_reference __x) const { return &__x; }

  pointer allocate(size_type __n, const void * hint = 0) {
      pointer tmp = static_cast<T*>(addr);
      addr = (void*)((char*)addr + __n);
      return tmp;
  }

  void deallocate(pointer __p, size_type __n) {
      // pMyPool->Free(reinterpret_cast<void *>(__p));
  }

 size_type max_size() const throw() {
    //return size_t(-1) / sizeof(T);
  }

 void construct(pointer __p, const T& __val) {
     ::new(__p) T(__val);
  }

 void destroy(pointer __p) {
    //__p->~T();
  }
};

typedef std::unordered_map<int, int, std::hash<int>, std::equal_to<int>,  MyPoolAlloc<std::pair<const int,int>> > Map;

int main ()
{
    shmid = shmget(shm_key, 1000, IPC_CREAT | IPC_EXCL | 644);
    if(shmid == -1){
            std::cerr << "Failed to create the shared segment." << strerror(errno)<< std::endl;
            exit(-1);
    }

    addr = shmat(shmid, NULL, 0);
    pool = addr;
    if(addr == (void*)-1){
            std::cerr << "Failed to attach the segment to the process." << std::endl;
            shmctl(shmid, IPC_RMID, 0);
            exit(-1);
    }

    Map *m = new(pool) Map;

    m->insert(std::pair<int, int>(2,4));

    shmdt(addr);
    shmctl(shmid, IPC_RMID, 0);

    return 0;
}

我正在为共享内存地址上的映射分配内存。我想对于元素,将使用分配器类的 allocate() 函数。但我无法弄清楚如何使用 allocate 函数为地图元素分配内存。 我在尝试插入地图的行处遇到算术异常。

有人可以帮助了解内存布局应该如何吗?

谢谢。

【问题讨论】:

  • 我已经编写了一些数据结构代码(哈希表、AVL 树),它提供了“链接”的抽象,并允许您使用其他东西而不是指针(例如,所有数组中的数组索引)条目)。在这里可能对你有很大帮助。见code.google.com/p/slib/wiki/GenericDataStructures_Introduction
  • 虽然不是完全抽象的;例如,哈希表对象仍然使用 malloc() 来构建存储桶数组(与条目数据相反),并存储指向该数组的指针,因此您应该小心。

标签: c++ shared-memory


【解决方案1】:

正如我所说的last time you asked about this,您不能将指针存储在共享内存中并期望它们在多个进程中可用。和以前一样,我建议使用boost::unordered_map in conjunction with boost::interprocess::allocator。

如果您真的想编写自己的分配器,您将需要某种自定义指针,将偏移存储到共享内存块中,并能够从中重建正确的地址。我不建议您自己尝试这样做:虽然它非常繁琐,但您可能会发现 std::unordered_map 的某些实现不能与非常规指针类型一起正常工作。事实上,我怀疑为共享内存制作一个符合标准的分配器可能是不可能的。否则,Boost 分配器肯定可以被所有标准容器使用,而不仅仅是特殊的 Boost 版本。

顺便说一句,你不应该在你自己的代码中使用像__p(包含双下划线)这样的保留名称;它们只能由标准库实现使用。

【讨论】:

  • 嘿,迈克,我只是想在跳转到 boost 进程间 impl 之前尝试一下,但没有获得足够的信息。
  • @mandeep:很公平。我猜不可能为共享内存编写符合标准的分配器。否则 Boost 分配器将可用于标准容器,而不仅仅是特殊的 Boost 版本。不过,也许他们错过了什么。
  • 迟到了。这是 MSVC xtree.h 文件中的一行(定义 map、set 等的基类):typedef _Node *_Nodeptr; // _Node allocator must have ordinary pointers
  • 如果在每个进程中为基地址选择相同的值,则可以将指针存储在共享内存中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-08
  • 1970-01-01
  • 1970-01-01
  • 2015-06-01
  • 2011-01-16
  • 1970-01-01
相关资源
最近更新 更多