【发布时间】:2016-01-26 14:01:15
【问题描述】:
这两种结构有什么区别? Clojure 文档提到后者添加了一个缓冲区。但我不清楚这意味着什么。
【问题讨论】:
标签: clojure clojurescript
这两种结构有什么区别? Clojure 文档提到后者添加了一个缓冲区。但我不清楚这意味着什么。
【问题讨论】:
标签: clojure clojurescript
如果一个通道被“附加”到一个总是获取其值的 go 块,那么一旦将值放入通道中,它们就会再次被取出。如果是这种情况,则通道的缓冲区大小无关紧要。
但考虑不存在这样的提取器的情况:
(def zero-buf-chan (chan))
(defn two-into-zero []
(go (>! zero-buf-chan :first)
(println "First into zero completed - NOT SEEN until run zero extractor")
(>! zero-buf-chan :second)
(println "Second into zero completed - NOT SEEN until run zero extractor")))
(two-into-zero)
这里什么都不会发生,因为zero-buf-chan 没有空间接受输入。这里的'go block'会在第一行暂停,等待退出。
如果我们现在将通道的大小设置为 1,那么它将有空间接受第一个输入,之后它将暂停:
(def one-buf-chan (chan 1))
(defn two-into-one []
(go (>! one-buf-chan :first)
(println "First into one completed - SEEN")
(>! one-buf-chan :second)
(println "Second into one completed - NOT SEEN until run one extractor")))
(two-into-one)
所以现在我们将看到
第一个完成 - 看到
在控制台中。
现在我们有两个暂停的 go 块。 one-buf-chan 中有 :first,zero-buf-chan 是空的。
为了完整起见,这里有两种可用于提取的方法:
(defn zero-extractor []
(go (println "Got from zero at first try: " (<! zero-buf-chan))
(println "Got from zero at second try: " (<! zero-buf-chan))))
(defn one-extractor []
(go (println "Got from one at first try: " (<! one-buf-chan))
(println "Got from one at second try: " (<! one-buf-chan))))
如果你运行这些函数,那么所有的printlns 都会被看到并且两个通道都会被清空。请注意,不会丢失任何数据。缓冲区的大小只是决定了多早发生阻塞。此外,需要注意的是,阻塞并不是阻塞你的程序,而是仅在 go 块内阻塞。
【讨论】: