62

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

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

4

6 回答 6

31

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

好处:更少的锁,可读的代码。

速度不是问题,至少不是由于 STM 的使用。

希望这可以帮助

于 2008-10-16T22:10:00.993 回答
28

文章“软件事务内存:为什么它只是一个研究玩具?(Călin Caşcaval 等人,ACM 通讯,2008 年 11 月),没有看 Haskell 的实现,这是一个很大的遗漏。正如文章所指出的那样,STM 的问题在于,实现必须在使所有变量访问都是事务性的,除非编译器可以证明它们是安全的(这会降低性能),还是让程序员指示哪些是事务性的(这会降低简单性)和可靠性)。然而,Haskell 实现使用 Haskell 的纯度来避免需要使大多数变量使用事务性,而类型系统提供了一个简单的模型以及对事务性变异操作的有效执行。因此,Haskell 程序可以将 STM 用于那些真正在线程之间共享的变量,同时保证非事务性内存使用是安全的。

于 2008-12-26T21:28:33.337 回答
28

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

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

于 2010-06-26T17:09:28.520 回答
12

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

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

我们正在 Scala 中构建临床系统的不同组件,并且到目前为止一直在使用 Actors,但我们真的缺少 STM。如果有人对在生产中使用 Scala STM 实现之一有什么经验,我很乐意听取您的意见。:-)

于 2011-12-06T17:49:51.053 回答
4

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

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

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

于 2011-12-09T17:19:28.757 回答
1

我目前在一些 PGAS 系统研究中使用 Akka。Akka是一个 Scala 库,用于使用 Actors、STM 和内置容错功能开发可扩展的并发系统,这些功能模仿 Erlang 的“让它失败/崩溃/火山口/ROFL”哲学。Akka 的 STM 实现据说是围绕 Clojure 的 STM 实现的 Scala 端口构建的。可以在这里找到 Akka 的 STM 模块的概述。

于 2011-04-17T17:56:50.170 回答