加速共享内存操作 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++的主要内容,如果未能解决你的问题,请参考以下文章

C++ 中具有共享内存的远程代理

C++文本处理的学习笔记

物理内存虚拟内存bufferscached共享内存swap

PHP服务缓存加速优化实战

C++指针

操作系统实验3共享内存进程间通信实验