2011-11-25 82 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并发工具都被设计为与他们自己和其他并发工具组合在一起

相关问题