简体   繁体   English

(chan)和(chan 1)有什么区别?

[英]What is the difference between (chan) and (chan 1)?

What is the difference between these two constructs? 这两种构造有什么区别? The Clojure docs mention that the latter adds a buffer. Clojure文档提到后者添加了一个缓冲区。 But it's not clear to me what that means. 但是我不清楚这意味着什么。

The number creates a fixed buffer which is used to hold values, so when you use ie >!! 该数字会创建一个用于保存值的固定缓冲区,因此当您使用ie > !!时 it will block unless there is space in the buffer or something consumes immediatly. 除非缓冲区中有空间或立即消耗某些东西,否则它将阻塞。

So (chan) should be equivalent to (chan 0) - there is no buffer (buffer of size 0) 因此(chan)应等于(chan 0) -没有缓冲区(缓冲区大小为0)

Instead of a number you could also supply a specific buffer, see here in the "see also" section. 除了提供数字之外,您还可以提供特定的缓冲区,请参见此处的“另请参见”部分。

If a channel is 'attached' to a go block that is always taking its values, then as soon as values are put into the channel they will be taken out again. 如果通道“附加”到始终使用其值的go块,则一旦将值放入该通道,它们就会再次被取出。 If this is the case then the buffer size of the channel does not matter. 如果是这种情况,则通道的缓冲区大小无关紧要。

But consider the case where no such extractor exists: 但是考虑不存在这种提取器的情况:

(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)

Here nothing will happen because zero-buf-chan has no room to accept input. 在这里什么也不会发生,因为zero-buf-chan没有空间接受输入。 The 'go block' here will be paused at the first line, waiting for a withdrawal. 此处的“前进挡”将在第一行暂停,以等待提款。

If we now give the channel a size of 1 then it will have room to accept the first input, after which it will pause: 如果我们现在将通道的大小设置为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)

So now we will see 所以现在我们将看到

First into one completed - SEEN 首次完成-SEEN

in the console. 在控制台中。

Now we have two paused go blocks. 现在我们有两个暂停的执行块。 one-buf-chan has :first in it and zero-buf-chan is empty. one-buf-chan:first ,而zero-buf-chan是空的。

For completeness here are two methods that can be used to do the extracting: 为了完整起见,可以使用两种方法进行提取:

(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))))

If you run these functions then all the println s will be seen and both channels will be emptied out. 如果运行这些功能,则将显示所有println并且两个通道都将被清空。 Notice that no data is ever lost. 请注意,永远不会丢失任何数据。 The size of the buffer just determines how early blocking will occur. 缓冲区的大小仅决定早期阻塞的发生方式。 And furthermore is it good to note that blocking is not blocking your program, but blocking ONLY within the go block. 而且还要注意,阻塞并不是阻塞程序,而是仅阻塞go块。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM