理解代码:通过交流共享资源

Understanding the code : Sharing resources by communicating

我一直在努力理解中的代码 https://golang.org/doc/codewalk/sharemem/ 虽然我了解了大部分关于通过通道传递资源的部分,但我无法理解程序 运行 中的无限循环。当轮询器中的 "in" 通道时,程序如何无限执行 Poller 函数函数(从主函数接收)运行 只有 3 个轮询器执行例程?

我想到了 StateMonitor 具有无限循环的匿名 go 函数。但它无法在不从 Poller 函数接收的情况下更新 LogState。我假设程序无限地对 url 执行 Get 请求。

为了确认我所理解的没有错,我通过打开和关闭 wifi 来测试程序以查看日志是否发生变化。令我惊讶的是,它确实如此,进行了几次迭代,但之后它停止响应我的更改并继续显示相同的日志。那么,这是否意味着程序有问题?还是我没有理解一些基本概念?

How does the program execute Poller function infinitely when the "in" channel in poller function(that receives from main function) run only 3 poller go routines ?

因此,程序首先创建两个轮询器:

for i := 0; i < numPollers; i++ {
    go Poller(pending, complete, status)
}

然后发送三个资源到pending:

for _, url := range urls {
    pending <- &Resource{url: url}
}

每个 Poller 从 pending 中读取并轮询资源:

for r := range in {
    s := r.Poll()
    status <- State{r.url, s}
    out <- r
}

这段代码似乎是无限执行的,但它通常会阻塞从队列中读取。所以这个循环等待下一个值出现。

让我们虚拟地跨过它:

  1. 有两个Poller读取资源
  2. 程序将第一个资源发送到队列。
  3. 其中一个轮询器获取资源并开始池化。另一个等待。
  4. 有时程序会向队列发送新资源。
  5. 由于第一个轮询器忙,第二个轮询器解除阻塞并开始轮询。
  6. 程序发送第三个资源并阻塞,因为两个轮询器正忙。
  7. 当其中一个轮询器完成时,它会占用最后一个资源并继续。
  8. 同时,主程序从完整队列中读取值。

for r := range in { s := r.Poll() status <- State{r.url, s} out <- r } How does this code run infinitely? If it loops over "in" channel, and "in" gets its resources from pending queue, it should terminate after few iterations. I think this is exactly the part that I don't understand.

准确的说,in并没有从pending队列中获取资源。 in pending 队列。队列(或通道,我可以互换使用)可以通过调用 close 来关闭,但在未明确关闭之前,它被认为是活动的。从它读取的任何内容都会阻塞当前的 goroutine,直到给出下一个值。然后 gorotine 恢复。

我想你一直在考虑通道,就像它们是具有固定数量元素的数组一样。他们不是。考虑他们喜欢具有无限数量元素的数组,但阻塞读取可能会抛出异常(如果您不熟悉这个概念,则粗略地近似关闭队列)。

通道上的发送操作会阻塞,直到同一通道有可用的接收方:如果通道上的值没有接收方,则不能将其他值放入通道中。反之亦然:当通道不为空时,不能在通道中发送新值!因此发送操作将等到通道再次可用。

另一方面,通道的接收操作会阻塞,直到发送方可用于同一通道:如果通道中没有值,则接收方会阻塞。

要解锁通道,我们需要无限循环地从通道中提取数据。

这就是为什么程序在无限循环中发送和读取数据的解释。

这让我明白了。休眠函数实际上会导致无限循环。

https://groups.google.com/forum/#!searchin/golang-nuts/sunil/golang-nuts/FSx8GmoRaNM/Nz9CdSF_zh8J][1]