C++ 速度:命名共享内存vs内存映射文件vs普通内存

C++ 速度:命名共享内存vs内存映射文件vs普通内存,c++,windows,sql-server-2008,memory,C++,Windows,Sql Server 2008,Memory,假设我有一个服务器,在那里连接的客户机不断更新他们的库存 我可以在更新项目后将中的更改保存到数据库中,也可以在客户端离开会话后更新整个清单 如果我使用第一种方法,按照我目前的规格,我不能同时处理所有这些。如果我进行第二次更新,而我的应用程序由于某种原因死亡,则更新永远不会存储在数据库中 我能做些什么来解决这个问题? 我只能提出两种解决方案(都意味着校验和): 运行一个辅助应用程序,它只创建一个命名的共享内存。主应用程序将使用此内存来清点所有客户机,如果我的应用程序死机,则辅助应用程序将保持共享内

假设我有一个服务器,在那里连接的客户机不断更新他们的库存

我可以在更新项目后将中的更改保存到数据库中,也可以在客户端离开会话后更新整个清单

如果我使用第一种方法,按照我目前的规格,我不能同时处理所有这些。如果我进行第二次更新,而我的应用程序由于某种原因死亡,则更新永远不会存储在数据库中

我能做些什么来解决这个问题?

我只能提出两种解决方案(都意味着校验和):

  • 运行一个辅助应用程序,它只创建一个命名的共享内存。主应用程序将使用此内存来清点所有客户机,如果我的应用程序死机,则辅助应用程序将保持共享内存的活动状态,从而保持数据的活动状态,一旦主应用程序重新启动,这些数据就可以保存

  • 将每个客户端映射到一个文件,即user1.dat、user2.dat,如共享内存。然而,这不会减慢我的程序吗?或者它的速度和命名的共享内存一样快?(如果我理解正确,它应该也一样快)(这是我目前最热门的列表之一

  • 更新在这些有用的评论之后,希望这里有一个更好的主意:创建另一个线程,为每个客户端创建一个文件,并在每次项目更改后立即更新它。一旦用户离开,整个库存将作为单个事务存储在数据库中。意味着所有的更新都发生了,或者没有更新。如果服务器崩溃或关闭,我只需要再次运行它。不再有内存映射文件,当然我会在每次更新后刷新该文件,并确保我更新的部分已正确写入,即具有原子提交。我不完全确定这是否会加快速度,因为数据库和在每个文件中存储更新都会在一天结束时,使用硬盘
  • 更具体地说,第二种方法是:

    至少在windows中,是否可以保证以下三种方法在写/读操作中都同样快如果有任何延迟,我需要知道

    据我所知,即使是文件映射方法也会立即更新内存,但不会更新文件本身(这很好)

    注意事项:

    我的应用程序是用C++和Windows API编写的。这两种方法(内存映射文件和命名共享内存)都使用以下功能:

    CreateFileMapping
    
    OpenFileMapping
    MapViewOfFile
    
    • 主应用程序将每天更新一次,因此它可能最终得到一个null ptr或其他类似的东西。源代码有点旧,将由多人更新

    • 辅助应用程序只创建一次,除非需要,否则永远不会更新。因此,没有理由相信,如果代码编写得很好,将来就不会出现使其崩溃的bug

    想法(必要时忽略):

    也许辅助应用程序可以在不同步的情况下备份数据:首先检索校验和,然后获取整个清单。如果校验和不匹配,那么它会再次尝试

    也许另一种选择是使辅助应用程序成为实际处理项目的应用程序

  • 每次客户端更新项目时,更新都会直接发送到第二个应用程序,该应用程序将处理更新,然后在客户端离开后将更新存储到数据库中。因为这个应用程序非常小,而且不会改变,所以确保它不会死掉非常简单。然而,主应用程序将不断变化,这就是为什么它最终会错误地使用空指针或类似的东西,并突然死亡的原因

  • 如果机器坏了怎么办?更新不会被存储。我觉得你担心的是不同类型内存上操作的相对速度,但你需要担心容错性。错误的方法。标准解决方案是将消息队列与事务队列一起使用。使系统能够适应崩溃和断电,消息将保留在队列中,直到您在更新数据库后将其删除。微优化没有用处,它不必比网络和数据库更快。如果应用程序崩溃,它很可能会破坏共享内存的内容。您基本上需要某种类型的事务。如果你试图将其整合在一起,你就可以很好地重新发明数据库(可能很糟糕)。是的,使用输入缓冲区/队列。可以很好地控制来自缓冲区的流,并且应用程序只与队列交互。专注于这个界面。
    CreateFileMapping
    
    OpenFileMapping
    MapViewOfFile