multithreading - Clojure:pvalues 与 pcalls

标签 multithreading clojure parallel-processing concurrent-programming

我正在阅读 The Joy of Clojure ,在有关并行化的部分中,对函数 pvaluespmappcalls 进行了解释,并提供了每个函数的用法的简短示例。以下是针对 pvaluespcalls 给出的示例:

(defn sleeper [s thing] (Thread/sleep (* 1000 s)) thing)

(pvalues
  (sleeper 2 :1st)
  (sleeper 3 :2nd)
  (keyword "3rd"))

(pcalls
  #(sleeper 2 :1st)
  #(sleeper 3 :2nd)
  #(keyword "3rd"))

我理解两者之间的技术差异——pvalues 需要计算可变数量的“值”,而 pcalls 需要“任意数量的函数”没有参数,”被并行调用。在这两种情况下,都会返回结果的惰性序列。

我的问题本质上是,您什么时候会使用一个与另一个?似乎唯一的语义区别是您在每个参数之前都添加了一个 #pcalls,将它变成一个匿名函数。因此,纯粹从节省击键和简化代码的角度来看,只使用 pvalues 不是更有意义吗? -- 如果是这样,为什么还要有一个 pcalls 函数?

我用 pcalls 得到了它,你可以用一个符号来代替一个函数,但是如果你想用 pvalues 使用这样的函数,你可以把括号中的函数,以便调用它。

我对为什么 Clojure 具有这两个如此相似的函数感到有点困惑。有没有什么你可以用一个,但不能用另一个?一些人为的示例可能会有所帮助。

最佳答案

pvalues 是一个围绕 pcalls 的便捷宏,尽管因为宏不是一流的,它不能像函数那样组合或传递。这是一个只有 pcalls 有效的例子:

user> (defn sleeper [s thing] (Thread/sleep (* 1000 s)) thing)
#'user/sleeper

user> (def actions [#(sleeper 2 :1st) #(sleeper 3 :2nd) #(keyword "3rd")])
#'user/actions

user> (apply pcalls actions)
(:1st :2nd :3rd)

user> (apply pvalues actions)
CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/pvalues, compiling:(NO_SOURCE_PATH:1:1)

在 clojure 中设计 API 时,不要限制用户只能通过宏与您的库进行交互,这一点很重要,因为这样他们就会遇到诸如此类的限制。

关于multithreading - Clojure:pvalues 与 pcalls,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21340186/

相关文章:

c++ - 混合并行 : MPI and TBB

python - 并行 for 循环 python

.net - 使用 Invoke 的跨线程异常的堆栈跟踪

clojure - clojure 中的定点组合器

vim - 如何为 slimv 和 ritz 设置类路径

json - 如何在 Clojure 中获取以字符串形式存储在数据库中的日期?

python - 使用 joblib 会使程序运行得更慢,为什么?

java - 为什么我在这个 java Thread 程序中得到这个输出?

python - 如何在 pygtk 中使用线程

python - 如何让线程使用下一个尚未使用的对象?