在共享内存中映射

Map in Shared memory

本文关键字:映射 内存 共享      更新时间:2023-10-16

我正试图在共享内存中创建一个无序映射。我正在使用分配器来实现这个目的。

代码

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函数为映射的元素分配内存。在我试图插入地图的那一行,我得到了算术异常。

有人能帮忙了解一下内存布局应该是什么样子吗?

谢谢。

正如上次您询问此问题时所说,您不能将指针存储在共享内存中,并期望它们在多个进程中可用。和以前一样,我建议将boost::unordered_mapboost::interprocess::allocator结合使用。

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

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