与 Java/Scala 相比,有关 Haskell 并发编程的两个(相关)问题:
Haskeller 对并发数据结构有何用途?有没有类似于Java的
java.util.concurrent.{ConcurrentHashMap, ConcurrentSkipListSet, ..}
的东西。MVar (Map k v)
不算 :)。共享可变状态是邪恶的,但有时是必要的。是否有与 Java 的
ExecutorService
等效的东西? AFAIK,Haskell 线程(参见fork#
中的yield#
、GHC.Exts
等)都是由 RTS 中内置的东西来调度的。但是,如果我特别想使用 fork join 池,或者在线程池上安排一些计算,该怎么办?能够放置Future
在 Scala 中特定执行上下文确实很方便,但我不知道如何在 Haskell 中做到这一点。
最佳答案
关于这个主题可以写一整本书,所以我会尝试只触及您所询问的要点。
您可以使用
par
组合器安排在未来某个时间点进行的纯计算。 RTS已经为此实现了工作窃取队列,并且已经为每个 CPU 核心维护一个线程来运行它们。 (如果您将程序与适当的开关链接起来。)请注意,这对于不纯的代码没有任何帮助,并且不会让您指定代码在哪个线程或哪个核心上执行。对于共享可变存储,您有两种选择。
使用
MVar
显式锁定。这具有其他编程语言中锁定的所有常见陷阱。 (死锁、忘记锁定事物、锁定太多事物、锁定事物时间太长、锁定时间不够长……)因此MVar (Map k v)
绝对 很重要!STM。您似乎误解了这是做什么的。 STM 的全部要点是您不需要锁。它允许您使用共享的可变数据结构,“就好像”它们不是共享的,但它会自动防止数据争用、状态不一致以及不使用锁时出现的所有其他常见问题。它还允许线程同时等待多个条件。这是一个令人难以置信的框架!
如果您想在特定操作系统线程上运行代码,您可能会寻找
forkOS
而不是forkIO
。
鉴于您的用例,我怀疑 STM 可能就是您正在寻找的。如果您有想要执行的特定任务,请发布另一个问题,您可能会得到更具体的建议。
关于haskell - Haskell 中的并发编程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55909755/