私がテストしたように、新しいエージェントを作成するときに、新しいエージェントごとに個別のスレッドが使用されます。複数のエージェントを 1 つのスレッドで実行できますか?
私の考えは、(erlang のアクターのような) 10,000 個以上の軽量エージェントを作成することですが、それは Clojure にとっての課題ですか?
ありがとう
私がテストしたように、新しいエージェントを作成するときに、新しいエージェントごとに個別のスレッドが使用されます。複数のエージェントを 1 つのスレッドで実行できますか?
私の考えは、(erlang のアクターのような) 10,000 個以上の軽量エージェントを作成することですが、それは Clojure にとっての課題ですか?
ありがとう
これは正しくありません。エージェントは、コア数 + 2 のサイズのスレッド プールを使用します。したがって、クアッド コア マシンでは、10,000 以上のエージェントでも 6 つのワーカー スレッドしか使用しません。
とsend
、つまり。send-off
新しいスレッドで開始されます。
jucDelayQueue の使用を検討してください
これがどのように機能するかのスケッチです。
(delayed-function
ここでは少し面倒ですが、基本的には、キューに送信するために jucDelayed のインスタンスを構築します。)
(import [java.util.concurrent Delayed DelayQueue TimeUnit])
(defn delayed-function [f]
(let [execute-time (+ 5000 (System/currentTimeMillis))
remaining-delay (fn [t] (.convert t
(- execute-time
(System/currentTimeMillis))
TimeUnit/MILLISECONDS))]
(reify
Delayed (getDelay [_ t] (remaining-delay t))
Runnable (run [_] (f))
Comparable (compareTo [_ _] 0))))
;;; Use java's DelayQueue from clojure.
;;; See http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/DelayQueue.html
(def q (DelayQueue.))
(defn delayed
"put the function f on the queue, it will only execute after the delay
expires"
[f]
(.offer q (delayed-function f)))
(defn start-processing
"starts a thread that endlessly reads from the delay queue and
executes the function found in the queue"
[]
(.start
(Thread.
#(while true
(.run (.take q))))))
user> (start-processing)
user> (delayed #(println "Hello"))
; 5 seconds passes
Hello
(私の意見では素晴らしい) Overtone 音楽シンセサイザーをサポートするために開発された at-at ライブラリの関数at
は、特定の時点で関数を実行するためのきれいなインターフェイスを提供します。
(use 'overtone.at-at)
(def my-pool (mk-pool))
(after 1000 #(println "hello from the past!") my-pool)