(chan) 和 (chan 1) 有什么区别?
What is the difference between (chan) and (chan 1)?
这两种结构有什么区别? Clojure 文档提到后者添加了一个缓冲区。但是我不清楚那是什么意思。
数字创建了一个用于保存值的固定缓冲区,因此当您使用 >!! 时它将阻塞,除非缓冲区中有 space 或某些东西立即消耗。
所以 (chan)
应该等同于 (chan 0)
- 没有缓冲区(大小为 0 的缓冲区)
除了数字之外,您还可以提供特定的缓冲区,请参阅 "see also" 部分中的 here。
如果一个通道 'attached' 到一个总是取其值的 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)
所以现在我们将看到
First into one completed - 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
s都会被看到并且两个通道都会被清空。请注意,不会丢失任何数据。缓冲区的大小只决定了早期阻塞的发生时间。此外,请注意阻塞并不是阻塞您的程序,而是仅在 go 块内阻塞。
这两种结构有什么区别? Clojure 文档提到后者添加了一个缓冲区。但是我不清楚那是什么意思。
数字创建了一个用于保存值的固定缓冲区,因此当您使用 >!! 时它将阻塞,除非缓冲区中有 space 或某些东西立即消耗。
所以 (chan)
应该等同于 (chan 0)
- 没有缓冲区(大小为 0 的缓冲区)
除了数字之外,您还可以提供特定的缓冲区,请参阅 "see also" 部分中的 here。
如果一个通道 'attached' 到一个总是取其值的 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)
所以现在我们将看到
First into one completed - 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
s都会被看到并且两个通道都会被清空。请注意,不会丢失任何数据。缓冲区的大小只决定了早期阻塞的发生时间。此外,请注意阻塞并不是阻塞您的程序,而是仅在 go 块内阻塞。