这两种结构有什么区别? Clojure文档提到后者添加缓冲区。但我不清楚这意味着什么。
答案 0 :(得分:2)
该数字创建一个固定缓冲区,用于保存值,因此当您使用ie >!!时,它将阻止,除非缓冲区中有空间或立即消耗某些东西。
所以(chan)
应该等同于(chan 0)
- 没有缓冲区(大小为0的缓冲区)
您也可以提供特定缓冲区而不是数字,请参阅“另请参阅”部分中的here。
答案 1 :(得分:2)
如果某个频道“附加”到始终采用其值的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)
现在我们将看到
首先进入一个完成 - SEEN
在控制台中。
现在我们有两个暂停的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))))
如果您运行这些功能,则会看到所有println
,并且两个通道都将被清空。请注意,没有数据丢失。缓冲区的大小只决定了早期阻塞的发生方式。此外,值得注意的是,阻止不会阻止您的程序,而是仅阻止阻止程序。