11

由于我工作的政策,我无法使用高于 1.33.1 的 Boost 版本,也无法使用高于 4.1.2 的 GCC 版本。是的,这是垃圾,但我对此无能为力。Boost 1.33.1 不包含进程间库。

也就是说,我的一个项目需要在共享内存中放置一个std::map(或更可能是一个)。std::unordered_map当进程由单个进程(“服务器”)加载并由许多其他进程读取时,它只被写入/修改一次。我以前没有做过共享内存 IPC,所以这对我来说是一个相当新的领域。我看了看,shmget()但似乎我不能继续使用相同的共享内存密钥进行分配(我认为 STL 容器分配器需要)。

是否还有其他使用共享内存的 NON-BOOST STL 分配器?

编辑:已经完成了。Dobbs 博士早在 2003 年就有一篇关于如何做到这一点的文章,我开始将其用作参考。但是,代码列表不完整,指向它们的链接重定向到主站点。

编辑编辑:我不只是重写 Boost.Interprocess 的唯一原因是因为涉及的代码量。我只是想知道是否有专门针对 POSIX 共享内存的相对简短和简洁的东西,我可以从头开始重写,因为网络之间的数据传输也需要经过多天的审批流程......

4

2 回答 2

7

指针在共享内存中不起作用,除非您无法将共享内存固定在固定地址(在所有进程中都是一致的)。因此,您需要特定的类,它们要么是连续的(无指针),要么在映射共享内存的内存区域中具有偏移量(而不是指针)。

我们在非常相似的情况下使用共享内存:一个进程计算一组数据,将其放入共享内存中,然后向其他进程发出信号,它们可以将内存映射到自己的地址空间;之后的记忆永远不会改变。

我们采用的方法是使用POD结构 (*)(其中一些包括char xxx[N];用于字符串存储的属性)。如果你真的可以限制你的弦,你就是金子。就目前map而言:只读存储效率低下=>排序数组表现更好(为内存局部性欢呼)。所以我建议这样做:

struct Key {
    enum { Size = 318 };
    char value[Size];
};

struct Value {
    enum { Size = 412 };
    enum K { Int, Long, String };
    K kind;
    union { int i; long l; char string[Size]; } value;
};

然后只需有一个std::pair<Key, Value>您排序的数组 ( std::sort) 并在其上std::lower_bound用于搜索。您需要为键编写一个比较运算符,显然:

bool operator<(Key const& left, Key const& right) {
    return memcmp(left.value, right.value, Key::Size) < 0;
}

而且我同意 enum + union 技巧比 boost 变体更不吸引人(界面方面)……让界面变得更好取决于你。

(*) 实际上,不需要纯 POD。例如,拥有私有属性、构造函数和复制构造函数是完全可以的。所需要的只是避免间接(指针)。

于 2012-09-27T07:45:08.003 回答
0

简单的解决方法。从 Boost 1.51 创建您自己的“libNotBoost v1.0”。Boost 库允许这样做。因为它不再是 Boost,所以你很好。

于 2012-09-27T07:07:10.480 回答