2014-12-07 52 views
2

我有3个长时间运行的任务需要同步。它们是独立的,但调用线程必须等到三个完成才能继续。Clojure与期待同步

我可以为每个任务创建一个代理并等待它们,但代理并不是真正的正确的语义结构,因为每个代理只会被调用一次。

我真正想要的是等待3期货,或者更接近我试图实现的方法。

我可以等待期货而不是代理吗?

编辑:

我猜的答案仅仅是简单地DEREF未来每调用线程在一个循环,这将阻塞,直到他们都回来了。如果我想在这段时间内做“准备”工作,我可以将“defrefing”代码本身放在另一个未来。

回答

2

它看起来像你主要回答你自己的问题。我会添加我的2美分关于如何做到这一点。

(defn many-futures 
    [tasks] 
    (let [futures (for [task tasks] 
        (future (task)))] 
    (do-prep tasks) 
    (doseq [completion futures] 
     @completion))) 

这将做所有的期货并行,然后在所有期货完成后返回。如果您真的想在某处使用结果,您可以用(doall (for ...))代替doseq。或者,实际上,您可以跳过doall,然后只在实际访问结果后才阻止。更进一步,您可以返回期货本身的懒惰期,然后您可以通过deref访问其中的任何一个,而与其他人的完成状态无关。