为什么闭包突然有用于优化在多个内核上运行的程序?

elj*_*nso 6 concurrency closures programming-languages multicore

我读过一篇文章,声称闭包(或"块")是"多核战争"中的有用武器,因为

[...]它们允许您创建工作单元,每个工作单元都有自己的堆栈副本,因此不会踩到彼此的脚趾.更重要的是,你可以传递这些单位,就像它们是值一样,实际上它们包含一整堆值(双关语),以及执行某些操作的可执行代码.

现在,我不是辩论一般封闭的有效性可能还并发编程在共享内存模型,但什么是有一个线程,只作用于局部数据的差异(或过程,或演员,或...) ?

作为没有调度程序的线程的并发编程,它本身不是一个闭包吗?

什么是关闭具有非局部副作用?

Har*_*d L 4

争论的焦点是,在编程语言中使用闭包可以更轻松地在另一个线程中完成某些工作。我认为作者应该在该论证中提到高阶函数的重要性。

我最喜欢的高阶函数介绍是“为什么函数式编程很重要”,我不会在这里尝试呈现一个糟糕的副本。

因此,如果您要在 for 循环中执行闭包,那么使用闭包并不会免费为您提供并行性,例如

for (int i = 0; i < numElements; i++) {
  result[i] = closure(inputs[i], i);
}
Run Code Online (Sandbox Code Playgroud)

因为语言无法判断是否closure(a, b)以某种方式更改了结果或输入数组中的其他值。但是具有高阶函数的语言(例如map指定传递给的函数map不应查看或更改输入中的其他值)并防止其影响其他结果。因此,可以为您并行化函数式语言中常见的如下代码,而无需创建工作线程池并将闭包移交给它们:

results = map(closure, inputs, [0..numElements-1]);
Run Code Online (Sandbox Code Playgroud)

在这些语言中,闭包消除了在某处为短代码片段声明新函数的痛苦。这使得使用高阶函数变得更加有趣。

以下 Haskell 代码定义了一个函数f,该函数接受数字列表并返回一个列表,其中每个输入i都替换为2i+1。通过省去创建计算函数的麻烦,2i+1只需 1 行代码而不是 2 行。

f nums = map (\i -> 2*i+1) nums
Run Code Online (Sandbox Code Playgroud)

再次,请参阅“为什么函数式编程很重要”,以获取有关如何扩展到实际代码库的有力论据。

  • 但底线仍然是,闭包很有用,因为它们是闭包(简短而甜蜜),但并不是因为它们在进行并发编程时本质上提供了一些优势。闭包和并发之间没有联系。 (2认同)