gpt4 book ai didi

clojure - Core.async <! channel 僵局

转载 作者:行者123 更新时间:2023-12-02 21:10:19 29 4
gpt4 key购买 nike

当我期望 Alpha 表现得像 Beta 时,为什么它会提前停止? Alpha 和 Beta 之间的唯一区别是 >!put!,如下所述。

阿尔法:

user=> (def q (chan))
#'user/q
user=> (def counter (atom 0))
#'user/counter
user=> (defn mg [event-queue]
#_=> (go-loop [event (<! event-queue)]
#_=> (swap! counter inc)
#_=> (when (< @counter 4)
#_=> (println "counter: " @counter)
#_=> (>! event-queue {:a @counter}) ;; Here's the only difference
#_=> (println "event: " event)
#_=> (recur (<! event-queue)))))
#'user/mg
user=> (mg q)
#object[clojure.core.async.impl.channels.ManyToManyChannel 0x3a1ffd56 "clojure.core.async.impl.channels.ManyToManyChannel@3a1ffd56"]
user=> (put! q "hi")
counter: true
1
user=>

测试版:

user=> (def q (chan))
#'user/q
user=> (def counter (atom 0))
#'user/counter
user=> (defn mg [event-queue]
#_=> (go-loop [event (<! event-queue)]
#_=> (swap! counter inc)
#_=> (when (< @counter 4)
#_=> (println "counter: " @counter)
#_=> (put! event-queue {:a @counter}) ;; Here's the only difference
#_=> (println "event: " event)
#_=> (recur (<! event-queue)))))
#'user/mg
user=> (mg q)
#object[clojure.core.async.impl.channels.ManyToManyChannel 0x72c9b65a "clojure.core.async.impl.channels.ManyToManyChannel@72c9b65a"]
user=> (put! q "hi")
true
counter: 1
event: hi
counter: 2
event: {:a 1}
counter: 3
event: {:a 2}
user=>

同样有趣的是,执行 Alpha 后, channel #'user/q 已正确排队:

user=> (take! q println)
event: hi
{:a 1}
nil
user=>

Clojure 和 Clojurescript 中都会出现相同的结果。这是某种僵局,还是假设会发生?

最佳答案

这是预期的。

channel q创建时没有缓冲区,因此当使用 >! 放置值时,它将阻止(停放)go-loop直到另一个线程准备好使用 <! 的值.

解决此问题的一种方法是给出 q 1 槽缓冲器 (def q (chan 1)) 。缓冲区允许将 1 个值放入 channel 中,而不会阻塞发送者。

Beta 的行为有所不同,因为 put! 是异步的。调用者——它使用单独的线程将新值放入 channel 中。这可以避免阻塞当前的go-loop ,允许读取 channel 并继续进度。

关于clojure - Core.async &lt;! channel 僵局,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33832040/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com