猿问

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

我一直在尝试理解https://golang.org/doc/codewalk/sharemem/ 中的代码 虽然我得到了关于通过通道传递资源的大部分内容,但我无法理解程序运行的无限循环. 当 poller 函数中的“in”通道(从 main 函数接收)只运行 3 个 poller go 例程时,程序如何无限执行 Poller 函数?

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

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


慕村9548890
浏览 175回答 3
3回答

aluckdog

通道上的发送操作会阻塞,直到接收器可用于同一通道:如果通道上的值没有接收器,则不能将其他值放入通道。反之亦然:当通道不为空时,不能在通道中发送新值!因此发送操作将等待直到通道再次可用。另一方面,通道的接收操作会阻塞,直到发送方可用于同一通道:如果通道中没有值,则接收方将阻塞。要解锁通道,我们需要无限循环地从通道中提取数据。这就是程序在无限循环中发送和读取数据的原因。

慕田峪7331174

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

相关分类

Go
我要回答