2011-03-13 28 views
15

什麼是習慣Clojure方式創造一個線程在後臺循環做更新對一些共享裁判並且管理它的生活?我發現自己使用future來做這件事,但這感覺就像是一點點黑客,因爲我從不回報有意義的價值。例如: -產生和管理後臺線程的習慣Clojure方式

(future (loop [] (do 
    (Thread/sleep 100) 
    (dosync (...)) 
    (recur)))) 

而且,我必須要小心future-cancel這個時候不再需要後臺處理。關於如何在Clojure/Swing應用程序中進行編排的任何提示都會很好。例如。一個虛擬的JComponent被添加到我的UI中,當窗口關閉時負責消除線程可能是一個想法。

回答

8

您的循環中不需要do;這是隱含的。另外,雖然無條件循環再發生沒有什麼問題,但你也可以使用(while true ...)。

future是一個很好的工具;不要讓它打擾你,你永遠不會得到回報。這應該真的打擾你,如果你使用代理而不是未來,雖然 - 沒有價值的代理商是瘋狂的。

但是,誰說你需要future-cancel?只要讓你未來的步驟之一是檢查是否仍然需要。然後,您的代碼中沒有其他部分需要跟蹤未來並決定何時取消它們。所以像

(future (loop [] 
      (Thread/sleep 100) 
      (when (dosync 
       (alter some-value some-function)) 
      (recur)) ; quit if alter returns nil 
     )) 

將是一個可行的方法。

+0

調用'未來cancel'或「請取消」標誌量確實設置爲相同的事情。我仍然需要確保它在正確的時間和穩健的情況下發生。 (我想念RAII) – pauldoo 2011-03-13 20:54:25

+0

關於'do'和'while'的其他觀點當然是正確的。 :) – pauldoo 2011-03-13 20:55:07

+0

我不認爲我說你應該設置一個取消請求的標誌。如果您的後臺任務將在例如一千次迭代之後完成,或者窗口已關閉,則未來可以跟蹤這些事情並關閉它。有些東西比較複雜,需要更詳細的管理,對於那些你可能會使用未來取消的東西。 – amalloy 2011-03-13 23:17:27

-1

使用後臺重複任務代理整潔我看來

(def my-ref (ref 0)) 

(def my-agent (agent nil)) 

(defn my-background-task [x] 
    (do 
    (send-off *agent* my-background-task) 
    (println (str "Before " @my-ref)) 
    (dosync (alter my-ref inc)) 
    (println "After " @my-ref) 
    (Thread/sleep 1000))) 

現在,所有你需要做的就是啓動環

(send-off my-agent my-background-task) 

my-backgound-task功能後,將自身發送主叫代理它的調用完成了。

這是希基多麼富有執行的蟻羣示例應用程序重複任務的方式:Clojure Concurrency

+0

這是一個非常糟糕的主意。螞蟻殖民地是clojure 1.0。他只是這樣做,因爲那裏沒有期貨。 – nickik 2011-03-13 21:19:00

+3

你爲什麼認爲這是一個壞主意? – Maciej 2011-03-13 21:25:22