Clojure 有没有一种方法可以在一组期货并行执行时,将它们作为一个组进行阻止?

Clojure 有没有一种方法可以在一组期货并行执行时,将它们作为一个组进行阻止?,clojure,future,Clojure,Future,我希望能够等待一组函数。我希望它们并行执行,但在最后一个将来完成之前停止。(我不希望它们按顺序执行,就像使用(do@(future-1)@(future-2))) 差不多 (声明long-running-fn-1) (宣布长期运行-fn-2) (让[结果]全部等待 (长期运行-fn-1…) (长期运行-fn-2…) (打印“结果1”(第一个结果) (打印“结果2”(第二个结果)) 未来将在定义时添加到用于发送的同一线程池中。只要该池中有足够的空闲线程(其大小将略大于可用的CPU内核数),计算将立

我希望能够等待一组函数。我希望它们并行执行,但在最后一个将来完成之前停止。(我不希望它们按顺序执行,就像使用
(do@(future-1)@(future-2))

差不多

(声明long-running-fn-1)
(宣布长期运行-fn-2)
(让[结果]全部等待
(长期运行-fn-1…)
(长期运行-fn-2…)
(打印“结果1”(第一个结果)
(打印“结果2”(第二个结果))

未来将在定义时添加到用于发送的同一线程池中。只要该池中有足够的空闲线程(其大小将略大于可用的CPU内核数),计算将立即开始

(doall@(future…@(future…)
的问题是,第二个
future
直到第一个被撤销后才创建

下面是对代码的一个稍加修改的版本,它定义了两个期货(开始计算),然后取消其中一个期货;您将看到这只需要5秒,而不是10秒:

(time
  (let [future-1 (future (Thread/sleep 5000))
        future-2 (future (Thread/sleep 5000))]
    [@future-1 @future-2]))

下面是另一个示例,说明并行执行+同步解引用:

(letfn [(mk-fut [sleep-ms res]
          (future
            (Thread/sleep sleep-ms)
            (println "return" res "after" sleep-ms "ms")
            res))]
  (let [futures (mapv mk-fut
                      (repeatedly #(rand-int 2000))
                      (range 10))]
    (mapv deref futures)))

;; return 3 after 104 ms
;; return 8 after 278 ms
;; return 0 after 675 ms
;; return 6 after 899 ms
;; return 1 after 928 ms
;; return 2 after 1329 ms
;; return 9 after 1383 ms
;; return 4 after 1633 ms
;; return 5 after 1931 ms
;; return 7 after 1972 ms
;;=> [0 1 2 3 4 5 6 7 8 9]

(输出打印的顺序在调用之间会有所不同,而生成的向量将是相同的)您可以看到,所有的未来都是并行运行的,同时以特定的顺序生成和取消引用。

使用
pcall
pvalues

test1.core=> (pcalls #(inc 1) #(dec 5))
(2 4)
test1.core=> (pvalues (inc 1) (dec 5))
(2 4)

在内部,它们使用
pmap
并行执行函数,并在处理所有函数时返回延迟的结果序列。

它们总是并行执行,即使您只是串行请求结果。@charlesduff-我不这么认为。这
(time(doall@(future(Thread/sleep 5000))@(future(Thread/sleep 5000)))
需要10秒,这让我相信它在第一个未来阻塞,然后在第二个未来阻塞,而不是同时执行两个未来。使用
doall
很可能是错误的。它适用于一个或两个这样的参数,返回null。移动到创建向量。