簡體   English   中英

停止生產者/消費者循環的慣用方法?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM