小编Mat*_*ton的帖子

Clojure 函数在执行之前等待另一个函数完成

我需要一个函数,当使用特定的输入参数调用时,执行提供的函数 g,但只有在另一个提供的函数 f 使用相同的输入参数完成执行之后。还有一个要求,当使用相同的输入args多次调用该函数时,f仅在第一次调用时执行一次,其他调用等待此完成,然后直接执行g。

编辑:该解决方案应该在不同线程上并行运行时工作,并且还应该有效地使用线程。例如,阻塞应该基于每个输入而不是整个函数。

我对该功能的第一次尝试如下:

(defn dependent-func
  ([f g]
   (let [mem (atom {})]
     (fn [& args]
       (->> (get (locking mem
                   (swap! mem (fn [latch-map args]
                                (if (contains? latch-map args)
                                  latch-map
                                  (let [new-latch (CountDownLatch. 1)
                                        new-latch-map (assoc latch-map args new-latch)]
                                    (->> (Thread. #(do (apply f args)
                                                       (.countDown new-latch)))
                                         (.start))
                                new-latch-map))) args)) args)
            (.await))
       (apply g args)))))
Run Code Online (Sandbox Code Playgroud)

这似乎满足我的要求,并且等待 f 是基于每个输入的,所以我对此相对满意。最初我希望只使用交换!进行内存更新,但不幸的是交换!明确指出该函数位于 swap! 可以被多次调用(我在测试中看到过这一点)。因此,我最终不得不在更新时锁定内存,这真的很难看。

我确信一定有一种更干净的方法可以比我更好地利用 Closure 的并发机制,但到目前为止我还没有找到它。

任何建议将不胜感激。

谢谢,

马特。

concurrency atomic clojure

4
推荐指数
1
解决办法
1751
查看次数

标签 统计

atomic ×1

clojure ×1

concurrency ×1