将 mmap 与 C++ 和动态容器一起使用

Using mmap with C++ and dynamic containers

我正在尝试使用 mmap 在我的设备上的进程之间映射和共享数据。我的目标是嵌入式设备 运行 嵌入式 Linux

我的流程是使用 C++ 和 std::liststd::map 等容器实现的。显然容器的大小随着程序的运行而变化。

如果我使用一个在进程之间共享的结构,例如:

struct MYSTRUCT
{
    int val1;
    int val2;
    list <int> list1;
};

MYSTRUCT myStruct;

// later as the program runs for example...
myStruct.list1.push_back(100);

然后我想使用 mmap 映射它。 mmap的API如下:

void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);

对于length参数,我可以使用sizeof(myStruct) + myStruct.list1.size()吗?

For the length parameter, can I use sizeof(myStruct) + myStruct.list1.size() for example ?

不,因为:

  1. list.size() 是列表中元素的 count。您将需要 list.size() * sizeof(int) 来存储裸元素,但这不考虑 list 本身的存储或其节点开销 ...

  2. 您可能无论如何都无法访问列表的内部节点类型,因此您不能为 list.size() * sizeof(list<int>::node_type) 或其他任何东西保留 space

  3. 即使可以,节点通常也会包含指针,因此除非您可以保证它们映射到完全相同的地址,否则它们将无法在另一个进程中使用

  4. 如果你能做到那个,你还需要提供一个自定义分配器,它知道它应该首先在共享内存中分配节点(你不能只是 memcpy 一个链接列表,就好像它是一个连续的数据块一样)

tl;dr 你不能用标准库类型真正做到这一点。要么使用 Boost.Interprocess,要么将数据序列化到共享内存中,或者首先将其存储在共享内存中的平面 POD/trivial 布局中。