Java 使用同步... Haskell 使用什么?

Java uses synchronisation... What does Haskell use?

所以我是 Haskell 的新手,想知道,如果在多线程 Java 中使用同步来防止损坏,这在 Haskell 中是如何完成的?我只在 google 上发现无用或过于复杂的回复。

这个答案一般适用于函数式语言——不需要同步。由于函数式编程中的函数没有副作用:函数接受一个值和 return 一个值,因此没有可变状态。这些函数本质上是线程安全的。

您的问题有点模棱两可,因为可以将多线程用于并发或并行,这是具有不同解决方案的不同问题。

在这两种情况下,您都需要确保您的程序编译时支持 SMP 并且 运行 使用多个 RTS 线程:请参阅 GHC 手册的 section about concurrency

并发

正如其他人指出的那样,同步在绝大多数代码中都不是问题,因为您将主要处理纯函数。如果您 将可变状态和依赖它的库置于武装看守之下 虔诚地避免可变状态,除非它被正确地包裹在 纯 [=69 后面,否则在任何语言中都是如此=]。并发性是 Haskell 大放异彩的领域,因为它的语义 需要 纯度。类型用于 描述 不纯的操作,这使得在可能需要某种同步的地方发现代码变得非常容易。

通常,您的应用程序的状态将由 t运行sactional 数据库支持,该数据库将为您处理同步和持久性。 如果您的并发应用程序没有额外的状态,您根本不需要任何额外的同步。

在其他情况下,haskell 有一个方便的 Software Transactional Memory 实现。它允许您编写和组合以 imperative-looking 风格编写的代码,无需显式锁定,同时具有原子性和 gua运行 防止死锁的措施。这是编写并发代码的万无一失的方法。

最后,base 中有一些 low-level 原语可用:带有 IORef, semaphores, and MVars 的普通旧可变引用,它们可以像受互斥锁保护的变量一样使用。

base 中也有频道,但要注意:它们是无界的!

平行度

这也是 Haskell 由于其 non-strict 语义而大放异彩的领域。 Non-strictness 允许您编写代码以直接的方式表达您的逻辑,而不用拘泥于特定的评估顺序。

因此,您可以将 parallel evaluation strategy 与业务逻辑分开描述。编写并行代码只是将正确的注释放在正确的位置的问题。

这是 was/is 在 Bdellium 生产中使用的示例:

map outputParticipant parts `using` parListChunk 10 rdeepseq
^^^^^ business logic ^^^^^^         ^^^^ eval. strategy ^^^^

代码可以这样理解:Parallel worker 将完全评估将 outputParticipant 函数映射到 parts 列表中的各个项目的结果,以 10 个元素为一组分配工作。