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

I've been trying to understand the code in https://golang.org/doc/codewalk/sharemem/ Though I get most of the part about passing resources via channel, I'm unable to understand the infinite loop the program runs in. 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 ?

I get the idea of StateMonitor having anonymous go function with infinite loop. But it can't update LogState without receiving from Poller function. I'm assuming the program performs Get request to the urls infinitely.

To confirm that I'm not wrong about what I've understood, I tested the program by turning the wifi on and off to see if the log changes. To my surprise, it does, for few iterations but after that it stops responding to my change and keeps on showing the same log. So, does that mean program is buggy? Or is it that I haven't understood some fundamental concepts?

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 ?

So, first the program creates two Pollers:

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

then it sends three resources to pending:

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

Every Poller reads from pending and polls the resource:

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

This code seems to be executed infinitely, but it is blocking read from a queue, generally. So this loops wait for the next value to appear.

Let's virtually step over it:

  1. There is two Pollers reading resources.
  2. Program sends first resource to the queue.
  3. One of the pollers gets the resource and start to pool. Another one waits.
  4. At some moment the program sends new resource to the queue.
  5. As the first poller is busy, the second one gets unblocked and start polling.
  6. Program sends third resource and blocks as two pollers are busy.
  7. When one of the pollers completes, it takes the last resource and continues.
  8. At the meantime, the main program reads values from the complete queue.

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.

To be precise, in does not gets the resources from pending queue. in is pending queue. The queue (or channel, which I use interchangeably) can be closed by calling close but until it is not closed explicitly it is considered alive. Any reading from it blocks the current goroutine until the next value will be given. Then gorotine resumes.

I suppose that you keep thinking about channels like they are array with fixed number of elements. They are not. Consider they like array with infinite number of elements but with blocking read that may throw exception (that the rough approximation of closing the queue if you are not familiar with the concept).

A send operation on a channel blocks until a receiver is available for the same channel: if there’s no recipient for the value on channel, no other value can be put in the channel. And the other way around: no new value can be sent in channel when the channel is not empty! So the send operation will wait until channel becomes available again.

On the other hand a receive operation for a channel blocks until a sender is available for the same channel: if there is no value in the channel, the receiver blocks.

To unblock the channel we need to pull the data from the channel in an infinite loop.

This is the explanation why the program is sending and reading data in an infinite loop.

This makes me clear. Sleep function actually causes the infinite loop.

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