我需要在我的结构中创建一个类似队列的结构,用作共享内存。我怎样才能做到这一点 ?我的编译器是 Visual C++。
2 回答
我担心在共享内存中使用复杂的 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<T, A> 其中 A 是分配器类型。默认情况下,使用从堆中获取内存的标准 STL 分配器。
然后,您的自定义共享内存分配器需要知道可以从哪个共享内存地址准确分配内存。大多数 STL 实现中的分配器支持不能很好地处理分配器的每个实例数据(据我所知),因此您可能需要分配器中的一些全局/静态数据,以便它可以知道从哪里获取共享内存从。
总而言之,您最好编写一个在共享内存上操作的简单自定义队列类,如 1) 中所述。您可以使队列类使用静态大小的内存,例如它可以为队列中的 100 个对象保留空间,如果超出此限制,则操作将失败。
- 使用互斥锁来保护您的共享内存,无论它可能是什么数据类型或类。你的数据有多复杂并不重要。另请阅读有关互斥锁如何工作的文章和维基百科线程文章。您的共享数据必须在堆中或作为全局变量,但不能在堆栈中,即不是局部变量。
- 对于数据的所有访问,您必须:
- 锁定互斥锁
- 复制数据或写入数据(不要在这里花太多时间)
- 释放互斥锁
- 使用数据(如果复制出来)
- 您想为线程和互斥锁使用轻量级、开源、多平台 C++ 库吗?试试TinyThread++。它的许可证也适用于商业用途,是免费的。它仅包含 3 个文件。请参阅有关如何使用它的文档。C 版本是TinyCThread。