【问题标题】:writing an unordered map to the shared memory not working将无序映射写入共享内存不起作用
【发布时间】:2012-08-01 14:32:10
【问题描述】:

我正在尝试共享一个无序映射(哈希映射),但它在尝试在映射中插入数据的那一行出现浮点异常。

有人可以帮助了解我哪里出错了吗?

#include <iostream>
#include <string>
#include <unordered_map>

#include <sys/ipc.h>
#include <sys/shm.h>
int main ()
{
    std::unordered_map<std::string,double> *tmp;

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

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

    tmp = static_cast< std::unordered_map<std::string,double>* >(addr);
    tmp->insert (std::pair<std::string,double>("abc",1.2));

    shmdt(addr);
    return 0;
}

谢谢。

【问题讨论】:

  • 我不认为 shmat 返回的 std::unordered_map<:string>* 和 void * 类型与 static_cast 正常工作有关。

标签: c++ linux


【解决方案1】:

一般来说,您不能在进程之间共享复杂的结构。特别是一个进程的虚拟地址空间中的对象的指针在另一个进程中是无效的,而且大多数容器实现都会涉及到指针。

您可以查看Boost.Interprocess 库,其中包含适合共享的各种容器和分配器;特别是他们的unordered_map can be placed in shared memory 版本,只要你使用他们的共享内存分配器,所以你可以简单地将它用作std::unordered_map 的替代品(尽管你仍然需要替代@ 987654327@作为密钥)。

【讨论】:

  • 理论上,自定义分配器应该允许这样做。 (实际上,我有点怀疑。)
  • @JamesKanze:确实,我也持怀疑态度,甚至没有提出建议。您将依赖容器的非常一致的实现,如果某些实现失败,例如pointer 不是T*,我不会感到惊讶。
  • 那么它是否如此复杂以至于最好采用其他方法,如果是这样的话,最好的选择是什么?我希望跨进程共享哈希映射。请提出一些建议。我有点卡住了
  • @mandeep:正如我在回答中所说,我建议Boost.Interprocess;特别是,boost::unordered_map 使用 boost::interprocess::allocator。如果您在答案中follow the second link,您将看到一个将地图放入共享内存的示例,这应该可以帮助您入门。我的评论是指编写自己的自定义分配器;我建议你不要尝试。
  • 如果你在映射共享内存的时候选择了一个特定的基地址,你可以随意共享指针和复杂对象。为了处理复杂的对象,我们在字符串类、数组类、哈希类等中添加了代码,以检查对象分配在哪个池中并继续在该池中分配内存。由于我们将内存池的大小量化为 4GB 的倍数,因此可以通过将地址右移 32 来从地址中找到一个池。
【解决方案2】:

您将共享内存地址转换为指向映射的指针,但您从未调用构造函数在该地址实际创建映射。无论如何,这可能不会按照您想要的方式工作,因为映射可能会为自己使用的内存分配和释放内存,这些内存将来自堆,而不是来自您的共享内存区域。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-06
    • 2012-09-08
    • 1970-01-01
    • 1970-01-01
    • 2010-11-28
    • 1970-01-01
    • 2011-08-06
    相关资源
    最近更新 更多