给出:是各种嵌套集合的复杂结构,参考文献分散在不同的层次上。
需要:--一种在其他线程中继续进行写入的方式,以获取此类结构的快照。
因此,一个“读取器”线程需要在一个长事务中读取整个复杂状态。同时,“编写者”线程在多个短事务中进行修改。据我所知,在这种情况下,STM引擎利用参考文献的历史。
这里我们有一些有趣的结果。例如,读者在交易开始后的10秒钟内到达一些参考文献。编写者每1秒修改一次这个引用。这就产生了10个参考文献的历史值。如果超出了ref的:max-history限制,读取器事务将永远运行。如果超过:min-history,事务可能会多次重新运行。
但实际上,读者只需要一个参考值(第一个),而作者只需要最近的一个。历史列表中的所有中间值都是无用的。有没有办法避免这样的历史过度使用?
谢谢。
发布于 2011-12-19 11:50:05
对我来说,有大量嵌套参考的大型结构有点“设计味”。您实际上是在模拟一个可变的对象图,如果您相信Rich的并发性,这是个坏主意。
有一些不同的想法要尝试:
发布于 2011-12-17 20:28:22
对你问题的一般回答是,你需要两件事:
至于如果队列溢出,因为快照进程不够快,那么除了优化进程或增加队列大小之外,没有什么可以做的--这将是一种平衡,取决于应用程序的需求。这是一个微妙的平衡,并将进行一些相当广泛的测试,这取决于您的系统有多复杂。
但你走的路是对的。如果您基本上将系统置于“快照写入模式”中,那么您的读取器/写入方法应自动更改它们从何处读取/写入的位置,以便正在进行更改的线程获取所有“当前值”,而读取快照状态的线程则读取所有“快照值”。您可以将它们分成不同的方法-快照阅读器将使用“快照值”方法,所有其他线程将读取“当前值”方法。
当快照阅读器完成其工作时,它需要清除快照状态。
如果线程在当前没有设置“快照状态”时尝试读取“快照值”,则应该使用“当前值”进行响应。没什么大不了的。
允许为备份目的拍摄文件系统快照的系统,同时不阻止写入新数据,请遵循类似的方案。
最后,除非您需要保存所有更改到系统的记录(即用于审计跟踪),否则事务队列实际上不需要是要应用的更改队列--它只需要存储系统中任何更改的最新值。当清除“快照状态”时,只需将所有未提交的值写入系统,并将其称为完成。您可能需要考虑的是记录那些尚未进行的更改,以防您需要从崩溃中恢复,并且仍然应用这些更改。日志文件将为您提供所发生的事情的记录,并允许您执行此恢复。这是对恢复过程的过度简化,但这并不是你的问题所在,所以我将就此结束。
发布于 2012-05-01 23:40:41
你所追求的是高性能并发的最先进的状态。您应该看看Nathan的工作,以及他与Aleksandar、Phil和Scala团队的合作。
二叉树:http://ppl.stanford.edu/papers/ppopp207-bronson.pdf https://github.com/nbronson/snaptree/
数组树-based散列映射http://lampwww.epfl.ch/~prokopec/ctries-snapshot.pdf
然而,快速查看上面的实现应该可以让您相信,这不是“滚动自己”的领域。如果可能的话,我会尝试调整一个现成的并发数据结构来满足您的需要。我链接到的所有内容在JVM上都是免费可用的,但它不是本地Clojure的。
https://stackoverflow.com/questions/8544990
复制相似问题