[英]Idiomatic approach to stopping producer/consumer go-loops?
為了獲得一些好的並發編程實踐,我正在嘗試使用 Clojure 的 core.async 庫來實現生產者/消費者模式。 一切正常,但我希望能夠在某個時間點停止生產者和消費者。
我當前的代碼看起來像這樣......
(def c (a/chan 5))
(def alive (atom true))
(def producer (a/go-loop []
(Thread/sleep 1000)
(when @alive
(a/>! c 1)
(recur))))
(def consumer (a/go-loop []
(Thread/sleep 3000)
(when @alive
(println (a/<! c))
(recur))))
(do
(reset! alive false)
(a/<!! producer)
(a/<!! consumer))
不幸的是,“do”塊有時會無限期地阻塞。 我基本上希望能夠阻止兩個循環繼續並阻塞,直到兩個循環都退出。 線程/睡眠代碼用於模擬執行某些工作單元。
我懷疑停止生產者會導致消費者停車,因此懸而未決,盡管我不確定其他方法,有什么想法嗎?
有關詳細信息,請參閱 ClojureDocs 。 例子:
(let [c (chan 2) ]
(>!! c 1)
(>!! c 2)
(close! c)
(println (<!! c)) ; 1
(println (<!! c)) ; 2
;; since we closed the channel this will return false(we can no longer add values)
(>!! c 1))
對於您的問題,例如:
(let [c (a/chan 5)
producer (a/go-loop [cnt 0]
(Thread/sleep 1000)
(let [put-result (a/>! c cnt)]
(println "put: " cnt put-result)
(when put-result
(recur (inc cnt)))))
consumer (a/go-loop []
(Thread/sleep 3000)
(let [result (a/<! c)]
(when result
(println "take: " result)
(recur))))]
(Thread/sleep 5000)
(println "closing chan...")
(a/close! c))
結果
put: 0 true
put: 1 true
take: 0
put: 2 true
put: 3 true
closing chan...
put: 4 false
take: 1
take: 2
take: 3
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.