似乎最近对STM(软件事务内存)框架和语言扩展的兴趣日益增加。 Clojure特别有一个很好的实现,它使用MVCC (multi-version concurrency control)而不是滚动提交日志。 GHC Haskell也有an extremely elegant STM monad,它也允许交易组成。最后,为了给我自己的号角做一点点,我最近实现了STM framework for Scala,它静态地强制执行参考限制。
所有这些都是有趣的实验,但它们似乎仅限于那个领域(实验)。所以我的问题是:你们有没有在现实世界中看到过或使用过STM?如果是这样,为什么?它带来了什么样的好处?性能怎么样? (在这一点上似乎存在大量相互矛盾的信息)你会再次使用STM还是更喜欢使用像演员一样的其他并发抽象?
答案 0 :(得分:30)
我参与了Haskell中BitTorrent客户端的爱好者开发(命名为conjure)。它使用STM来协调不同的线程(每个对等1个用于存储管理,1个用于整体管理)。
好处:减少锁,可读代码。
速度不是问题,至少不是由于STM的使用。
希望这有帮助
答案 1 :(得分:27)
文章“软件交易记忆:为什么它只是一个研究玩具?”没有看到Haskell实现,这是一个非常大的遗漏。正如文章所指出的,STM的问题在于,实现必须在使所有变量访问事务处理之间进行选择,除非编译器能够证明它们是安全的(这会导致性能下降)或者让程序员指出哪些是事务性的(这会导致简单性和可靠性)。然而,Haskell实现使用Haskell的纯度来避免使大多数变量使用事务性的需要,而类型系统提供简单的模型以及事务变异操作的有效实施。因此,Haskell程序可以将STM用于线程之间真正共享的变量,同时保证非事务性内存使用保持安全。
答案 2 :(得分:27)
我们经常在Galois(在Haskell中)的高并发应用程序中使用它。它可以工作,它在Haskell世界中广泛使用,并且它没有死锁(当然你可以有太多的争用)。有时我们会改写使用MV的东西,如果我们的设计正确 - 因为它们更快。
只需使用它。这没什么大不了的。就我而言,Haskell中的STM是“已经解决”的。没有进一步的工作要做。所以我们使用它。
答案 3 :(得分:12)
我们factis research GmbH正在使用Haskell STM和GHC进行生产。我们的服务器从临床“数据服务器”接收关于新的和修改的“对象”的消息流,它动态地转换这个事件流(通过生成新对象,修改对象,聚合事物等)并计算这些新事件中的哪一个对象应与已连接的iPad同步。它还接收来自iPad的表单输入,这些输入被处理,与“主流”合并并且还与其他iPad同步。我们将STM用于需要在线程之间共享的所有通道和可变数据结构。 Haskell中的线程非常轻量级,所以我们可以在不影响性能的情况下使用很多线程(目前每个iPad连接有5个)。构建大型应用程序始终是一项挑战,需要学习许多课程,但我们从未遇到任何STM问题。它总是像你天真的期待一样工作。我们不得不做一些严肃的性能调整,但STM从来都不是问题。 (80%的时间我们试图减少短期分配和总体内存使用。)
STM是Haskell和GHC运行时真正发挥作用的一个领域。这不仅仅是一项实验,也不适用于玩具程序。
我们在Scala中构建了一个不同的clincal系统组件,到目前为止一直使用Actors,但我们确实缺少STM。如果有人体验过在生产中使用Scala STM实现之一的感受,我很乐意听取您的意见。 : - )
答案 4 :(得分:4)
我们已经在C中自己的STM实现之上实现了我们的整个system(内存数据库和运行时)。在此之前,我们有一些基于日志和锁的机制来处理并发,但是这个维持是一种痛苦。我们对STM非常满意,因为我们可以以同样的方式对待每个操作。几乎所有的锁都可以被移除。我们现在几乎可以使用任何规模的STM,我们甚至还有一个内存管理器。
表现还不错,但为了加快速度,我们现在与苏黎世联邦理工学院合作开发了一个定制operating system。该系统本身支持事务性内存。
但是STM也会带来一些挑战。特别是对于导致不必要的事务冲突的较大事务和热点。例如,如果两个事务将项目放入链接列表,则会发生不必要的冲突,这可能是使用无锁数据结构避免的。
答案 5 :(得分:1)