当 poller 函数中的“in”通道(从 main 函数接收)只运行 3 个 poller go 例程时,程序如何无限执行 Poller 函数?
所以,首先程序创建两个轮询器:
for i := 0; i < numPollers; i++ {
go Poller(pending, complete, status)
}
然后它将三个资源发送到待处理:
for _, url := range urls {
pending <- &Resource{url: url}
}
每个轮询器都从挂起中读取并轮询资源:
for r := range in {
s := r.Poll()
status <- State{r.url, s}
out <- r
}
这段代码似乎是无限执行的,但它通常会阻止从队列中读取。所以这个循环等待下一个值出现。
让我们虚拟地跨过它:
- 有两个 Pollers 阅读资源。
- 程序将第一个资源发送到队列。
- 其中一个轮询器获取资源并开始池化。另一个等着。
- 在某个时刻,程序将新资源发送到队列。
- 由于第一个轮询器很忙,第二个轮询器被解除阻塞并开始轮询。
- 当两个轮询器忙时,程序发送第三个资源和块。
- 当其中一个轮询器完成时,它会获取最后一个资源并继续。
- 同时,主程序从完整队列中读取值。
for r := range in { s := r.Poll() status <- State{r.url, s} out <- r }
这段代码如何无限运行?如果它在“in”通道上循环,并且“in”从待处理队列中获取资源,它应该在几次迭代后终止。我想这正是我不明白的部分。
准确地说,in
不从pending
队列中获取资源。in
是 pending
队列。队列(或通道,我可以互换使用)可以通过调用close来关闭,但在没有明确关闭之前,它被认为是活动的。从它读取的任何内容都会阻塞当前的 goroutine,直到给出下一个值。然后 gorotine 继续。
我想您一直在考虑通道,就像它们是具有固定数量元素的数组一样。他们不是。考虑他们喜欢具有无限数量元素的数组,但具有可能引发异常的阻塞读取(如果您不熟悉该概念,则关闭队列的粗略近似值)。