在clojure中创建10k +代理

时间:2012-08-07 13:24:44

标签: concurrency clojure actor agents

正如我测试的那样,当我创建它们时,每个新代理都使用一个单独的线程。 几个代理可以在一个线程中运行吗?

我的想法是创建10K +轻量级代理(如erlang中的actor),这对Clojure来说是一个挑战吗?

由于

3 个答案:

答案 0 :(得分:9)

这是不正确的。代理使用线程池,其大小为核心+ 2的数量。所以在四核机器上,即使是10k +代理也只能使用6个工作线程。

send即是。使用send-off新线程将启动。

答案 1 :(得分:3)

考虑使用j.u.c.DelayQueue

这是一个如何运作的草图,

delayed-function在这里有点麻烦,但它基本上构造了一个j.u.c.Delayed实例以提交给队列。)

(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

答案 2 :(得分:0)

the at-at libraryat函数,用于支持(在我看来太棒了)Overtone音乐合成器为在特定时间点运行函数提供了一个很好的干净 interfase

(use 'overtone.at-at)
(def my-pool (mk-pool))
(after 1000 #(println "hello from the past!") my-pool)