为什么并发Haskell是非确定性的,而并行Haskell原语(par和pseq)是确定性的?

19
在Haskell的并发和并行上下文中不太理解“决定论”,一些示例会很有帮助。谢谢。
2个回答

25

在处理纯值时,求值的顺序并不重要。这就是 并行性 的本质:并行地评估纯值。与纯值相反,对于具有副作用的操作,通常情况下顺序很重要。同时运行动作称为并发性

例如,考虑两个操作 putStr "foo"putStr "bar"。根据这两个动作获取执行的顺序,输出可能为 "foobar"、"barfoo" 或介于两者之间。由于它依赖于特定的计算顺序,因此输出是不确定的

再例如,考虑两个值 sum [1..10]5 * 3。无论这两个的计算顺序如何,它们都将归结为相同的结果。这种确定性通常只能通过纯值来保证。


22
+1;换言之,平行性是一种优化方式;而并发则改变语义。 - ehird
在 Oz 语言中:1. 数据流值只能绑定一次。2. 程序使用未绑定的值时应等待其被绑定。因此,当两个线程使用同一个数据流值时,行为是确定性的。 - jiamo

25

并发性和并行性是两个不同的概念。

并发性意味着您有多个线程在非确定性地互动。例如,您可能有一个聊天服务器,其中每个客户端由一个线程处理。这种非确定性对于您试图建模的系统至关重要。

并行性是使用多个线程仅仅是为了使程序运行更快。但最终结果应该与按顺序运行算法时完全相同。

许多语言没有并行性原语,因此您必须使用诸如线程和锁之类的并发原语来实现它。然而,这意味着您作为程序员必须小心,以确保您不会意外引入不需要的非确定性或其他并发问题。使用显式并行性原语(例如parpseq),许多这些问题都可以轻松解决。


并发不一定涉及多个线程,事件循环可以用于在单线程环境中提供并发性(JavaScript 是一个例子)。 - ximo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接