任何使用软件事务性内存的真实世界体验



最近人们似乎对STM(软件事务内存)框架和语言扩展越来越感兴趣。Clojure尤其有一个出色的实现,它使用MVCC(多版本并发控制)而不是滚动提交日志。GHC Haskell还有一个非常优雅的STM monad,它还允许事务组合。最后,我最近为Scala实现了一个STM框架,它静态地强制执行引用限制。

所有这些都是有趣的实验,但它们似乎仅限于这个领域(实验)。所以我的问题是:你们中有人在现实世界中见过或使用过STM吗?如果是,为什么?它带来了什么样的好处?性能如何?(在这一点上,似乎有很多相互冲突的信息)你会再次使用STM,还是更喜欢使用其他一些像actor一样的并发抽象?

我在Haskell(名为Magic)参与了BitTorrent客户端的爱好者开发。它大量使用STM来协调不同的线程(每个对等端1个+存储管理1个+整体管理1个)。

优点:锁更少,代码可读。

速度不是问题,至少不是因为STM的使用。

希望这能帮助

我们在Galois(Haskell)的高并发应用程序中经常使用它。它是有效的,在Haskell世界中被广泛使用,而且它不会死锁(当然,你可能会有太多的争论)。有时,如果我们的设计正确的话,我们会重写一些东西来使用MVar,因为它们更快。

用它吧,没什么大不了的。就我而言,Haskell中的STM已经"解决"了。没有进一步的工作要做。所以我们使用它。

文章"软件事务性内存:为什么它只是一个研究玩具?"(Călin-Caşcaval et al.,Communications of The ACM,2008年11月)没有研究Haskell的实现,这是一个很大的遗漏。正如文章所指出的,STM的问题在于,实现必须在以下两者之间做出选择:要么让所有变量访问都是事务性的,除非编译器能够证明它们是安全的(这会影响性能),要么让程序员指示哪些是事务性访问(这会降低简单性和可靠性)。然而,Haskell实现使用了Haskell的纯粹性,以避免需要使大多数变量使用事务性,而类型系统提供了一个简单的模型以及事务性变异操作的有效实施。因此,Haskell程序可以对线程之间真正共享的变量使用STM,同时保证非事务内存的使用是安全的。

我们,facts research GmbH,正在生产中使用带有GHC的Haskell STM。我们的服务器从临床"数据服务器"接收关于新的和修改过的"对象"的消息流,它会动态转换此事件流(通过生成新对象、修改对象、聚合事物等),并计算这些新对象中的哪些应该同步到连接的iPad。它还接收来自iPad的表格输入,这些输入经过处理,与"主流"合并,并与其他iPad同步。我们将STM用于所有通道和需要在线程之间共享的可变数据结构。Haskell中的线程非常轻,因此我们可以在不影响性能的情况下拥有大量线程(目前每个iPad连接5个)。构建一个大型应用程序总是一个挑战,有很多经验教训需要学习,但我们在STM方面从未遇到过任何问题。它总是像你天真地期望的那样起作用。我们不得不进行一些认真的性能调整,但STM从来都不是问题。(80%的时间我们都在努力减少短暂的分配和整体内存使用。)

STM是Haskell和GHC运行时真正大放异彩的领域之一。这不仅仅是一个实验,也不仅仅是玩具程序。

我们正在Scala中构建一个不同的临床系统组件,到目前为止一直在使用Actors,但我们确实缺少STM。如果有人有在生产中使用Scala STM实现的经验,我很想听听你的意见。:-)

我们已经在C中实现了我们自己的STM实现之上的整个系统(内存数据库和运行时)。在此之前,我们有一些基于日志和锁的机制来处理并发,但维护起来很麻烦。我们对STM非常满意,因为我们可以用同样的方式对待每一次手术。几乎所有的锁都可以拆除。我们现在几乎对任何大小的东西都使用STM,我们甚至在上面实现了内存管理器。

性能不错,但为了加快速度,我们现在与苏黎世联邦理工学院合作开发了一个自定义操作系统。系统本机支持事务性内存。

但STM也带来了一些挑战。尤其是在较大的事务和热点会导致不必要的事务冲突的情况下。例如,如果两个事务将一个项目放入链表,就会发生不必要的冲突,而使用无锁数据结构本可以避免这种冲突。

我目前正在一些PGAS系统研究中使用Akka。Akka是一个Scala库,用于使用Actors、STM和以Erlang的"Let It Fail/Crash/Crater/ROFL"哲学为模型的内置容错功能开发可扩展的并发系统。Akka的STM实现据说是围绕Clojure的STM实施的Scala端口构建的。Akka STM模块的概述可以在这里找到。

最新更新