加速共享内存操作 C++
Posted
技术标签:
【中文标题】加速共享内存操作 C++【英文标题】:Speeding up shared memory operations c++ 【发布时间】:2014-03-03 14:22:19 【问题描述】:我有一个dll
应用程序,它是用Visual Studio 2008 VC++
编写的。基本上它有两个到外部应用程序的接口。
其中一个是给作家的:
class writer_interface
virtual void write (myData data, unsigned long id) = 0;
另一个是针对阅读器应用的:
class reader_interface
virtual select(unsigned long id) = 0;
virtual select(time_t insertionTime) = 0;
所以我将元数据保存在共享内存中的容器中,我正在使用boost managed_shared_memory
。
问题是外部编写器应用程序在一秒钟内调用我的写入函数 15 次,而读者在一秒钟内同时对我的共享内存容器进行 5 次查询。
因此,对于我的 Write 方法的每个 Write 函数调用,我必须打开共享内存并像这样找到我的容器:
//Open the managed segment
managed_shared_memory segment(open_only, "MySharedMemory");
//Find the vector using the c-string name
MyVector *myvector = segment.find<MyVector>("MyVector").first;
但是在我拥有如此频繁的数据的情况下,这个成本太高了。因为每次打开共享内存并在其中查找容器几乎都需要100 milliseconds
。这意味着由于共享内存操作存在瓶颈。
阅读器应用也会出现同样的瓶颈情况。
我的问题是如何使这些共享内存操作更快? 有没有办法防止每次在共享内存中打开和重新找到容器?
谢谢。
【问题讨论】:
你不能把find的结果和segment对象一样缓存吗? 我试图将它分配为类属性,如变量或 smth,但每次重新进入类时它都会丢失其值。你的意思是什么类型的缓存? 【参考方案1】:在内存中缓存最近打开的段是一个好主意。假设您将缓存最近打开的 10 个段。创建一个单例类,该类将保存一个将字符串映射到段对象的字典。每次您需要从任何段读取/写入时,您将检查此单例是否已经包含它(通过某些 id - 例如它的名称)。如果是 - 您将获得它的引用/指针并对其进行读/写。否则,您将打开一个新段并将其存储在此单例中。
Singleton 是一个可能只有一个实例的类,通常在第一次使用时创建。请参阅下一个链接http://forums.codeguru.com/showthread.php?423850-how-to-implement-a-singleton-in-c-c。 我会这样做。
在头文件中:
class Singleton
public:
static Singleton* instance();
void write (myData data, unsigned long id);
void select(unsigned long id);
void select(time_t insertionTime);
private:
Singleton();
static Singleton* m_singleton; // singleton instance
managed_shared_memory m_segment;
;
在 cpp 文件中: 单例* 单例::m_singleton= NULL;
Singleton::Singleton()
: segment(open_only, "MySharedMemory")
// do init stuff
Singleton* Singleton::instance()
if (m_singleton== NULL)
m_singleton = new Singleton();
return m_singleton;
void Singleton::write (myData data, unsigned long id)
//Find the vector using the c-string name
MyVector *myvector = m_segment.find<MyVector>("MyVector").first;
// add code here
void Singleton::select(unsigned long id)
// your code here
void Singleton::select(time_t insertionTime)
// your code here
在write_interface的实现器中的使用:
Singleton::instance().write (data, id);
方案只保证一个实例,从程序开始到结束。
【讨论】:
实际上在我的代码中它也是单例的,但可能是我做错了。我明天试试你的方法,在这里通知。感谢您的回答。 是的,关键部分是:":segment (open_only ..." 确实谢谢。【参考方案2】:在内存中缓存最近打开的段是一个好主意。 假设您将缓存最近打开的 10 个段。 创建一个单例类,该类将保存一个将字符串映射到段对象的字典。 每次您需要从任何段读取/写入时,您将检查此单例是否已经包含它(通过某些 id - 例如它的名称)。如果是 - 您将获得它的引用/指针并对其进行读/写。否则,您将打开一个新段并将其存储在此单例中。
【讨论】:
其实我应该只有两个段。一个段用于编写器应用程序(只有一个编写器),另一段用于阅读器应用程序(它们应该共享同一段)但是每当程序退出相关方法时,我都会丢失该段。我的意思是它的作用域看起来像是一个在方法中创建的局部变量。我尝试通过将其作为属性添加到类来使该段全局化,但它不起作用。如何将细分保持为单例? 在我的示例中,我只使用了一个片段,但如果您愿意,可以使用 2 个片段以上是关于加速共享内存操作 C++的主要内容,如果未能解决你的问题,请参考以下文章