6

私はいくつかのロボットとコントローラーを持っているシミュレーションをいじっています、コントローラーは何をすべきかを決定し、ロボットに仕事を割り当てます、以下は技術的には虐待です基本的に私はエージェントの状態を気にしません、私はそれが送信されたfnsを順番に実行し、終了するのを待つことができます。

以下は、私が達成しようとしていることをほぼ示しています。コントローラーは、各ロボットがそのチャンクを取得するという大きな仕事を取得します。


(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の並行性ツールを使用してこれを行うことは可能ですか、それとも構造のようなエージェントを再実装する必要がありますか?

4

1 に答える 1

6

エージェントアクション内から好きなだけ送信または送信できます。

実際にはできないことは、エージェント内から別のエージェントが完了するのを待つことです。メッセージが言うように。

これは良いことです。エージェントで待機できるようにすると、明らかにデッドロックが発生する可能性があるからです。clojureの並行性プリミティブのポイントは、ルールに従ってプレイする場合、デッドロック(およびその他の並行性関連の問題)を不可能にすることです。

IMOのユースケースはエージェントにとって理想的ではありません。inbox queueこれらは、アクターの部分と同様に、非同期の同期ポイントとなることを目的としています。その機能は必要なく、単なるジョブランナーとして使用するので、プレーンJavaExecutorServiceを使用した方がサービスが向上すると思います。

また、 ForkJoinフレームワークも興味深いかもしれません。これは、基本的に、計算の小さな単位をフォークして、(おそらく)結果が必要な瞬間にそれらを待つことです。

于 2011-08-15T08:45:12.987 に答える