doujuanqi2909 2018-06-03 15:26
浏览 37

难以理解电子书中的并发示例

I'm having difficulty understanding concurrency from an ebook. My hopes are someone can do a breakdown step by step with me so i can clearly understand whats going on.

Here is the main method:

func main(){
  c := make(chan int)
  go printer(c)
  wg.Add(1)

  // Send 10 integers on the channel.
  for i := 1; i <= 10; i++ {
    c <- i
  }

  close(c)
  wg.Wait()
}

And here is the printer method:

func printer(ch chan int) {
    for i := range ch {
        fmt.Printf("Received %d ", i)
    }
    wg.Done()
}

Here are my questions:

  • Why are we only executing wg.Add(1) as one group to wait for instead of wg.Add(1) inside the main method for loop
  • I'm really not understanding channels, period.

I've done some research and no one seems to be able to explain it to me in a simple way.

Any step by step simple explanation as to sending integers on channel and adding to wait groups would be appreciated.

UPDATE

sourcecode => https://github.com/goinaction/code/blob/master/chapter1/channels/hellochannels.go

  • 写回答

2条回答 默认 最新

  • dsf12123 2018-06-03 15:50
    关注

    Editor's note: this first paragraph was in response to the author's original code, which has since been edited to have markedly different semantics than the code that was originally presented.

    The code example you've provided is not a particularly good example as far as demonstrating the usage of a WaitGroup, because the program is terminated by the end of the main method rather than any co-ordination handled by the WaitGroup. You can remove the call to wg.Done() and that program will still compile and execute fine.

    I'm happy to answer your more general questions, though.

    Why are we only executing wg.Add(1) as one group to wait for instead of wg.Add(1) inside the main method for loop?

    It sounds like you're asking why we don't increment wg for each integer in the for loop. This is not really the point of WaitGroups. A typical use case would be adding 1 for each goroutine that we're co-ordinating beyond the main goroutine. In this example, there's one other goroutine (the one handling printer, so we only add 1 to our WaitGroup.

    A more clear version of your above example would be something like the following:

    var wg sync.WaitGroup
    
    func printer(ch chan int) {
        for i := range ch {
            fmt.Printf("Received %d ", i)
        }
        wg.Done()
    }
    
    func sender(ch chan int) {
        for i := 0; i <= 10; i++ {
            ch <- i
        }
        close(ch)
    }
    
    func main() {
        c := make(chan int)
        go printer(c)
        go sender(c)
        wg.Add(1)
    
        fmt.Println("Waiting...")
        wg.Wait()
        fmt.Println("Finished")
    }
    

    In this example, we want to wait for the printer method to have fully printed off all of its numbers we proceed with the main goroutine. So we tell our main goroutine to Wait() until all integers have been printed, at which point we tell the main thread to proceed. Unlike your example, we close the channel once we've entered all of our ints into it, which allows the printer function to stop blocking on range and to go ahead and call wg.Done - in your original example, the printer never stops blocking on range and so never actually calls wg.Done

    I'm really not understanding channels, period.

    Hopefully the above example makes things a little more clear? I'm afraid this part of your question is a bit too broad for me to answer.

    评论

报告相同问题?

悬赏问题

  • ¥15 关于#MATLAB#的问题,如何解决?(相关搜索:信噪比,系统容量)
  • ¥500 52810做蓝牙接受端
  • ¥15 基于PLC的三轴机械手程序
  • ¥15 多址通信方式的抗噪声性能和系统容量对比
  • ¥15 winform的chart曲线生成时有凸起
  • ¥15 msix packaging tool打包问题
  • ¥15 finalshell节点的搭建代码和那个端口代码教程
  • ¥15 Centos / PETSc / PETGEM
  • ¥15 centos7.9 IPv6端口telnet和端口监控问题
  • ¥20 完全没有学习过GAN,看了CSDN的一篇文章,里面有代码但是完全不知道如何操作