所以我对Haskell很新,并且想知道,如果在多线程Java时使用同步来防止损坏,那么在Haskell中如何完成?我只是在谷歌上发现无用或过于复杂的回复。
答案 0 :(得分:6)
你的问题有点模棱两可,因为人们可能会使用多线程来实现并发或并行,这是不同解决方案的明显问题。
在这两种情况下,您都需要确保您的程序是使用SMP支持编译的,并使用多个RTS线程运行:请参阅GHC手册的section about concurrency。
正如其他人所指出的,同步在绝大多数代码中都不是问题,因为你将主要处理纯函数。如果您保持可变状态,并且在武装警卫下依赖它的库,那么在任何语言中都是如此,除非它正确地包装在纯API 之后,否则会豁免可变状态。并发是Haskell发光的一个领域,因为它的语义需要纯度。类型用于描述不纯的操作,这样就很容易找到可能需要某种同步的代码。
通常,您的应用程序的状态将由事务数据库支持,该数据库将为您处理同步和持久性。 如果并发应用程序没有其他状态,则根本不需要任何其他同步。
在其他情况下,haskell有一个方便的Software Transactional Memory实现。它允许您编写和编写以命令式样式编写的代码,无需显式锁定,同时具有原子性并防止死锁。它是编写并发代码的 万无一失(tm)方式。
最后,base
中提供了一些低级原语:带有IORef
,semaphores和MVars
的普通旧可变引用,可以像使用它们一样使用是由互斥体保护的变量。
base
中也有频道,但要注意:它们是无界的!
这也是Haskell因其非严格语义而发光的领域。 Non-strictness 允许您编写代码,以直接的方式表达您的逻辑,同时不会致力于特定的评估订单。
因此,您可以与业务逻辑分开描述parallel evaluation strategy。编写并行代码只需将正确的注释放在正确的位置即可。
以下是Bdellium生产中使用的示例:
map outputParticipant parts `using` parListChunk 10 rdeepseq
^^^^^ business logic ^^^^^^ ^^^^ eval. strategy ^^^^
代码可以理解如下:并行工作人员将完全评估将outputParticipant
函数映射到parts
列表中的各个项目的结果,将工作分布在10个元素的块中。
答案 1 :(得分:0)
这个答案通常与功能语言有关 - 不需要同步。函数式编程中的函数没有副作用:函数接受一个值并返回一个值,没有可变状态。这些函数本质上是线程安全的。