【问题标题】:STL structure inside Shared Memory共享内存中的 STL 结构
【发布时间】:2013-07-13 11:31:31
【问题描述】:

我需要在我的结构中创建一个类似队列的结构,用作共享内存。我怎样才能做到这一点 ?我的编译器是 Visual C++。

【问题讨论】:

  • 试试 Boost.Interprocess。
  • 不使用外部库不可行吗?
  • 真的是不同进程共享内存吗?
  • 是的。一个进程将创建一个共享内存并将整数放入队列。另一个人会阅读它们。

标签: c++ visual-c++ shared-memory


【解决方案1】:

我担心在共享内存中使用复杂的 C++ 对象并不是那么简单。您必须考虑两件事。

1)

您需要在共享内存区域而不是堆栈上创建类实例。您可以通过使用placement new 操作符来做到这一点。示例:

#include <new> // for placement new operator

class X
{
     // whatever
};

// suppose this points to some shared memory area
void *shared_mem = getSharedMem();

// this creates an instance of X at the start address of shared_mem
new(shared_mem) X;

// now you have a reference to an instance of X in the shared memory area
X& shared_x = *reinterpret_cast<X*>(shared_mem);

但是请注意,只有一个进程应该负责在共享内存中构造该对象。此外,参与的其他进程也需要一种方法来了解对象是否已经正确初始化并且可以安全地访问。 Access 还需要某种进程间锁定(例如,在 Win32 上一个命名的互斥锁)

2)

如果您的类类型需要动态内存,就像队列数据结构的情况一样,那么内存不能像往常一样来自堆,因为堆对于一个进程来说是本地的。如果您想使用 STL 队列容器,那么您可以实现自己的 STL 分配器类,该类不是从堆中获取内存,而是从共享内存中获取内存。

使用的分配器类是 STL 模板声明的一部分。例如 std::deque 其中 A 是分配器类型。默认情况下,使用标准 STL 分配器从堆中获取内存。

然后,您的自定义共享内存分配器需要知道可以从哪个共享内存地址准确分配内存。大多数 STL 实现中的分配器支持不能很好地处理分配器的每个实例数据(据我所知),因此您可能需要分配器中的一些全局/静态数据,以便它可以知道从哪里获取共享内存来自。

总而言之,您最好编写一个在共享内存上操作的简单自定义队列类,如 1) 中所述。您可以让队列类使用静态大小的内存,例如它可以为队列中的 100 个对象保留空间,如果超过此限制,则操作失败。

【讨论】:

  • 另一个进程如何访问共享内存中的对象? (假设对象已经成功初始化并且其他进程知道共享内存的地址)
【解决方案2】:
  1. 使用mutex 来保护您的共享内存,无论它是什么数据类型或类。你的数据有多复杂并不重要。另请阅读有关how mutexes work 和wikipedia Threads 的文章。您的共享数据必须在堆中或作为全局变量,但不能在堆栈中,即不是局部变量。
  2. 对于数据的所有访问,您必须:
    • 锁定互斥体
    • 复制数据或写入数据(不要在这里花太多时间)
    • 释放互斥锁
    • 使用数据(如果复制出来)
  3. 您想为线程和互斥锁使用轻量级、开源、多平台 C++ 库吗?试试TinyThread++。它的许可证也适用于商业用途,是免费的。它仅包含 3 个文件。请参阅有关如何使用它的文档。 C 版本为TinyCThread。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-11
    • 1970-01-01
    • 1970-01-01
    • 2016-02-24
    相关资源
    最近更新 更多