【问题标题】:Wants to create an application storing data in memory. But i dont want the data to be lost even if my app crashes [closed]想要创建一个在内存中存储数据的应用程序。但即使我的应用程序崩溃,我也不希望数据丢失[关闭]
【发布时间】:2015-01-08 23:49:26
【问题描述】:

想要创建一个在内存中存储数据的应用程序。但即使我的应用程序崩溃,我也不希望数据丢失。 我应该使用什么概念? 我应该使用共享内存,还是有其他概念更适合我的要求。

【问题讨论】:

  • 到目前为止你尝试了什么?
  • 使用mysql 或其他一些数据库。
  • 定期将数据保存在磁盘上的文件中会有所帮助。
  • 转储数据库或文件中的数据会使应用程序变慢。此外,我在想如果我使用共享内存或类似的东西,我可以重新启动我的应用程序,它可以从同一点恢复工作,我不必为恢复数据编写任何逻辑。
  • @user3131441 不是真的,如果你定期这样做只是为了保存对数据的更改,虽然它不会恢复最新信息,但至少会将其中一些信息恢复到最后一个保存点

标签: c++ linux shared-memory memory-mapped-files


【解决方案1】:

您要求persistence(甚至正交持久性)和/或application checkpointing

对于某些任意现有 C++ 代码,例如,在一般情况下,这是不可能的(至少通过可移植 C++ 代码)因为ASLR,因为指向-或指向-本地call stack的指针,因为多threading,以及因为外部资源(套接字,打开的文件,...),因为当前continuation无法在标准 C++ 中访问、恢复和处理。

但是,您可能设计您的应用程序考虑到持久性。这是一个强大的架构要求。例如,您可以让每个类都包含一些转储方法及其加载工厂函数。当心共享指针,并考虑到您可能有循环引用。研究类似于持久化所需的garbage collection 算法(例如在Gc HandBook 中)(复制GC 非常类似于检查点算法)。

还可以查看serialization 库(如libs11n)。您还可以考虑将持久化为文本格式(例如JSON),可能在一些Sqlite 数据库中(或一些真实的数据库,如PostGreSQLMongoDb....)。我正在我的monimelt 软件中执行此操作(在 C 中)。

您也可以考虑检查点库,例如 BLCR

重要的是在设计时非常尽早考虑持久性和检查点。将您的应用程序视为一些专门的 bytecode 解释器或 VM 可能会有所帮助(特别是如果您想保持延续,或某种形式的“调用堆栈”)。

您可以在持久化之前分叉您的进程(假设您在 Linux 或 Posix 上)。因此,持久化时间并不重要(例如,如果你每小时或每十分钟坚持一次)。

一些语言实现能够持久化它们的整个状态(尤其是它们的堆),例如SBCL(一个很好的 Common Lisp 实现)及其 save-lisp-and-die,或 Poly/ML -an ML dialect- 及其 SaveState,或 SqueakSmalltalk 实现)。

另见this answerthat one。 J.Pitrat 的博客有一个相关条目:CAIA as a sleeping beauty

数据与代码的持久性(例如对象的vtables、函数指针)在技术上可能很困难。 dladdr(3) -with dlsym- 可能会有所帮助(而且,如果您能够编写机器特定的东西,请考虑旧的getcontext(3),但我不建议这样做)。通过声明extern "C"所有与持久性相关的代码来避免name mangling(对于dlsym)。如果您想保留一些数据并能够通过稍微修改的程序(例如小错误修复)从它重新启动,事情就复杂得多。

更务实的是,您可以拥有一个代表整个可持久状态的类,并实现方法来持久化(并重新加载它)。然后,您将仅在算法的某些步骤中坚持(例如,如果您有一个主循环或 event loop,则在该循环开始时)。您可能不想太频繁地持久化(例如,因为持久化所需的时间和磁盘空间),例如也许每十分钟一次。如果它适合您的应用程序的整体情况,您可能会考虑使用一些 transaction log

【讨论】:

    【解决方案2】:

    使用内存映射文件 - mmap (https://en.wikipedia.org/wiki/Mmap) 并在映射内存区域内分配所有结构。当您的应用崩溃时,系统会正确地将映射文件保存到磁盘。

    【讨论】:

    • 可能因为 ASLR 和大多数标准 C++ 容器在该区域之外分配数据而无法工作。
    • @BasileStarynkevitch 我们可以使用自定义分配器或使用普通的C 数组。我们需要存储什么样的数据?可以很好C++ template 解决方案:)
    • 那么每个容器模板都应该与特定于应用程序的分配器一起使用。
    猜你喜欢
    • 2011-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多