有没有办法在并行执行时采用一组期货并将它们作为一个组来阻止?

Is there a way to take a set of futures and block on them as a group while they execute in parallel?

我希望能够等待一组函数。我希望它们并行执行,但会阻塞直到最后一个 future 完成。 (我不希望它们按顺序执行,例如 (do @(future-1) @(future-2))

类似

(declare long-running-fn-1)
(declare long-running-fn-2)

(let [results (wait-for-all
   (long-running-fn-1 ...)
   (long-running-fn-2 ...)]

     (println "result 1" (first results)
     (println "result 2" (second results))

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

(doall @(future ...) @(future ...)) 的问题是第二个 future 直到 第一个被取消引用后才创建。

这里是你的代码的一个稍微修改过的版本,它定义了 both 个期货(开始计算),然后再取消对它们中的任何一个的引用;你会看到它只需要 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]

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

使用pcallspvalues:

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

他们在内部使用 pmap 并行执行函数,并在处理所有函数时使用 return 惰性结果序列。