3 回答
TA贡献1847条经验 获得超7个赞
通道上的发送操作会阻塞,直到接收器可用于同一通道:如果通道上的值没有接收器,则不能将其他值放入通道。反之亦然:当通道不为空时,不能在通道中发送新值!因此发送操作将等待直到通道再次可用。
另一方面,通道的接收操作会阻塞,直到发送方可用于同一通道:如果通道中没有值,则接收方将阻塞。
要解锁通道,我们需要无限循环地从通道中提取数据。
这就是程序在无限循环中发送和读取数据的原因。
TA贡献1828条经验 获得超13个赞
当轮询函数中的“in”通道(从主函数接收)仅运行 3 个轮询 go 例程时,程序如何无限执行轮询函数?
因此,首先该程序创建两个轮询器:
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
}
这段代码似乎是无限执行的,但它通常会阻止从队列中读取。所以这个循环等待下一个值出现。
让我们实际上跳过它:
有两个 Poller 阅读资源。
程序将第一个资源发送到队列。
其中一个轮询器获取资源并开始池化。另一个等待。
在某个时刻,程序将新资源发送到队列。
当第一个轮询器忙时,第二个轮询器被解除阻塞并开始轮询。
程序发送第三个资源并在两个轮询器忙时阻塞。
当其中一个轮询器完成时,它会占用最后一个资源并继续。
同时,主程序从完整队列中读取值。
for r := range in { s := r.Poll() status <- State{r.url, s} out <- r }
这段代码如何无限运行?如果它在“in”通道上循环,并且“in”从挂起队列中获取其资源,则它应该在几次迭代后终止。我想这正是我不明白的部分。
准确地说,in
不从pending
队列中获取资源。in
是 pending
队列。队列(或通道,我可以互换使用)可以通过调用close 关闭,但直到它没有被明确关闭,它才被认为是活动的。对它的任何读取都会阻塞当前的 goroutine,直到给出下一个值。然后 gorotine 继续。
我想您一直在考虑通道,就像它们是具有固定数量元素的数组一样。他们不是。考虑到他们喜欢具有无限数量元素的数组,但具有可能引发异常的阻塞读取(如果您不熟悉这个概念,这是关闭队列的粗略近似值)。
- 3 回答
- 0 关注
- 174 浏览
添加回答
举报