简体   繁体   English

停止生产者/消费者循环的惯用方法?

[英]Idiomatic approach to stopping producer/consumer go-loops?

In an effort to get some good concurrent programming practice I'm trying to implement the producer/consumer pattern using Clojure's core.async library.为了获得一些好的并发编程实践,我正在尝试使用 Clojure 的 core.async 库来实现生产者/消费者模式。 All is working well but I wanted to be able to stop both the producer and consumer at some point in time.一切正常,但我希望能够在某个时间点停止生产者和消费者。

My current code looks something like this...我当前的代码看起来像这样......

(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))

Unfortunately it appears that the 'do' block occasionally blocks indefinitely.不幸的是,“do”块有时会无限期地阻塞。 I essentially want to be able to stop both go-loops from continuing and block until both loops have exited.我基本上希望能够阻止两个循环继续并阻塞,直到两个循环都退出。 The Thread/sleep code is there to simulate performing some unit of work.线程/睡眠代码用于模拟执行某些工作单元。

I suspect that stopping the producer causes the consumer to park, hence the hanging, though I'm not sure of an alternative approach, any ideas?我怀疑停止生产者会导致消费者停车,因此悬而未决,尽管我不确定其他方法,有什么想法吗?

Please see ClojureDocs for details.有关详细信息,请参阅 ClojureDocs Example:例子:

(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))

For your problem something like:对于您的问题,例如:

  (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))

with result结果

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.

相关问题 Java生产者消费者问题 - Producer Consumer issue in Java 在 Asyncio 中兼顾生产者和消费者 Python - Juggle Producer and Consumer in Asyncio Python Apache Camel Restlet消费者和生产者 - Apache Camel Restlet Consumer and Producer C#等待生产者/消费者中的多个事件 - C# Await Multiple Events in Producer/Consumer Fast producer,slow consumer,bounded channel,降低唤醒producer的频率 - Fast producer, slow consumer, bounded channel, reduce the frequency of awakening the producer python 3.5的绑定缓冲区(生产者/消费者) - Bounded Buffer (producer/consumer) with python 3.5 如何处理TPL数据流中的异常-生产者/消费者 - How to handle Exceptions in a TPL Dataflow - Producer/Consumer 在消费者端处理失败的呼叫(在生产者/消费者模型中) - Handling Failed calls on the Consumer end (in a Producer/Consumer Model) C ++ STL生产者多个消费者,其中生产者在产生下一个价值之前等待免费消费者 - C++ STL Producer multiple consumer where producer waits for free consumer before producing next value 如何在API中将实现生产者使用者管道的类暴露给客户端代码? - How to expose a class implementing producer consumer pipeline to client code in an API?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM