concurrency - 使用代理同步作业

标签 concurrency clojure agent

我正在玩一个模拟,我有几个机器人和一个 Controller , Controller 决定做什么并将工作分配给机器人,从技术上讲,以下是一种滥用,基本上我不关心代理状态,我只关心它的事实将按顺序执行发送给它的 fns,我可以等待它们完成。

以下几乎展示了我想要实现的目标, Controller 得到了一份大工作,每个机器人都得到了一大块,
(def *agents* (reduce (fn[h v] (assoc h v (agent true))) {:control (agent true)} (range 0 5))) (defn send-job [id f] (send-off (*agents* id) (fn [s f] (try (f) (catch Exception e (println e)))) f)) (defn await-job [id] (await (*agents* id))) (send-job :control (fn [] (send-job 0 (fn [] (Thread/sleep 10) (println "0 Done."))) (send-job 1 (fn [] (Thread/sleep 2))) (await-job 1) ;; 0 still running. ;; do other stuff... ))
好吧,问题是你不能在送出中送出,我得到“不能在代理行动中等待”。是否可以使用 clojure 的并发工具来做到这一点,或者我是否必须重新实现类似结构的代理?

最佳答案

您可以随心所欲地从代理操作中发送或发送。

实际上,您不能做的是等待另一个代理从代理内部完成。就像消息所说的那样。

这是一件好事,因为允许在代理中等待显然会导致可能的死锁。如果您遵守规则,clojure 并发原语的重点是使死锁(和其他与并发相关的问题)不可能发生。

IMO 您的用例不适合代理。它们旨在成为异步同步点,类似于 inbox queue部分 Actor 。由于您不需要该功能而仅将它们用作工作运行器,因此我认为使用纯 Java ExecutorService 会更好地为您服务。 .

同样感兴趣的可能是 ForkJoin框架,它基本上是关于在您进行时 fork 计算的小单元,并(可能)在您需要结果的那一刻等待它们。

关于concurrency - 使用代理同步作业,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7056243/

相关文章:

java - 如何使该 Java 代码可并行化?如何使其可云化?

objective-c - 核心数据: concurency conflict between save and fetch

c - 在 C 代码中使用 ReadFile

java - 如何将参数从 Main 提供给 Anylogic 中的代理

TFS 构建代理没有响应

java - threadPoolExecutor 内存溢出异常

emacs - 有没有更简单的方法可以从 emacs/cider 同时使用 BOTH clj + cljs REPL?

json - JQ 无法解析 Unicode 表情符号字符。它是有效的 JSON 吗?

namespaces - 在 Clojure 中,在 ns 宏中使用 require ... as 而不是 use... 在地道上是否正确

java - 证书仅受信任一次