2011-11-25 77 views
3

最近我一直在試驗Clojure的多線程特性,並試圖實現一個簡單的併發問題。在下面的代碼我運行函數寫一個代理,並嘗試將作業發送到另一個代理,但在這行的程序塊:Clojure代理可以調用​​另一個代理嗎?

(doseq [j (range (count readers))] 
    (send (nth readers j) rr (inc j))) 

完整代碼:

(def state (ref 0)) 
(def readers (doall (map #(agent %) (repeat 3 0)))) 
(def writers (doall (map #(agent %) (repeat 3 0))))  

(defn rr [re] 
(println (format "Read about %s" @state)) 
(inc re) 
) 

(defn write [re topic] 
(dosync 
    (ref-set state topic) 
) 
(Thread/sleep (rand-int 1000)) 
(println "Wrote about" topic) 
(doseq [j (range (count readers))] 
    (send (nth readers j) rr (inc j))) 
(inc re) 
) 

(defn -main[] 
(dotimes [i 5] 
    (doseq [j (range (count writers))] 
    (send (nth writers j) write (inc j)))) 
    (dorun (map #(await %) writers)) 
    (dorun (map #(println "Writes:" @%) writers)) 
) 
+2

只是一個方面的評論,它不是特別習慣的lisp把封閉的parens放入換行符 – skuro

回答

4

我不是完全確定你想要做什麼,但功能rr被定義爲一個參數,但根據

(send (nth readers j) rr (inc j)) 

它實際上應該有兩個參數(第一個是CURREN代理的t值,第二個參數是(inc j)的值。

表達(agent-error (first writers))應揭露某種元數異常的(雖然我還沒有嘗試過)

2

Clojure的代理可以發送到其他代理內外搞出來的refsatoms。由該功能發送的任何消息都會保留,直到完成對代理的更改,因此您不必擔心他們與自己競爭。

上代理的主網頁對一個側面說明an example of arranging agents in a ring

,如果從refdosync則消息保證只發送一次內發送消息,事務提交。一般來說,所有的Clojure併發工具都被設計爲與他們自己和其他併發工具組合在一起

相關問題