将值放入然后立即从通道中删除会导致奇怪的行为(ClojureScript core.async)
以下是一个人为的学习示例。它包括将值将值放入然后立即从通道中删除会导致奇怪的行为(ClojureScript core.async),clojure,clojurescript,core.async,Clojure,Clojurescript,Core.async,以下是一个人为的学习示例。它包括将值“val”插入通道,然后立即在go块中移除: (def test-chan1 (chan)) (go (println (<! (go (do (>! test-chan1 "val") (<! test-chan1)))))) ; the return value of the (do..) is "val"
“val”
插入通道,然后立即在go块中移除:
(def test-chan1 (chan))
(go
(println
(<!
(go
(do
(>! test-chan1 "val")
(<! test-chan1)))))) ; the return value of the (do..) is "val"
; ...hence the return value of the nested go block should be a channel containing "val"
; hence (println ..) should eventually print "val" to the console
(def测试通道1(通道))
(去
(println
(!测试通道1“val”)
(
问题:为什么此代码段不将“val”打印到控制台?默认情况下,通道是同步的,因此put将被阻止,直到有人要获取(反之亦然)
因此,您的问题是,内部的go
在put(!
)上被永远阻止。请尝试将您的频道更改为(频道1)
默认情况下,频道是同步的,因此put将被阻止,直到有人可以获取(反之亦然)
所以,你的问题是,内部的go
在put(!
)上永远被阻止。试着把你的频道改成(频道1)
次要评论,你不需要“do”次要评论,你不需要“do”有效——但我完全不明白为什么:(我们不是在之后立即通过)(>!)
?为什么这不会导致go块停止阻塞?是因为您必须在同一个s表达式中(!..)
才能停止阻塞go块?(当go块在(>)中被阻塞时,表达式永远不会运行)
直到有什么东西把值从频道上取下来,!
被阻止(卡住)。它永远不会到达下一行。您需要另一个go块或线程从通道中获取。将1
参数添加到chan
函数中会给它一个1的缓冲区,以便可以在不阻塞推杆的情况下将一个值放在通道上(尽管任何进一步的值都会阻止他们的推杆,直到有东西从通道中取出)。另一种不阻止推杆的方法是使用put!
函数而不是函数。这是有效的——但我完全搞不懂为什么:(我们不是在之后立即通过(>)
?为什么这不会导致go块停止阻塞?是因为您必须在同一个s表达式中(!..)
才能停止阻塞go块?在(>!)中阻塞go块时,该(表达式永远不会运行)
,直到有东西将值从通道中移除,!
被阻塞(卡住)。它永远不会到达下一行。你需要另一个go块或线程从通道中取出。将1
参数添加到chan
函数中会给它一个1的缓冲区,这样一个值就可以放在通道上而不会阻塞推杆(尽管任何进一步的值都会阻止他们的推杆,直到有东西从通道中取出)。另一种不阻塞通道的方法是使用put!
函数而不是函数。