通道在func main()上发送和接收

时间:2018-12-19 00:22:43

标签: go

我一直在学习频道,教科书中的示例似乎简单易懂。但是,我无法理解以下行为。

func main() {
     message := make(chan string)

     message <- "ping"
     fmt.Println(<-message)
}

为什么上述结果会导致错误?我知道我可以通过引入go例程使发送方和接收方都准备就绪来使其工作。但是,如果是这样,为什么下面的方法起作用?

func main() {
    message := make(chan string,1)

    message <- "ping"
    fmt.Println(<-message)

}

*********感谢Joe McMahon的回答*********
*********以下文档供我参考*********
我假设缓冲区1(不同于2)也会阻塞主例程,直到找到相应的接收者为止。似乎缓冲区1的工作方式与0&1相似,并且不会阻塞第0次写/读的代码。为了演示使用缓冲区的块,

func main() {
    message := make(chan string, 1)

    message <- "ping1"
    message <- "ping2"
    fmt.Println(<-message) //Unreachable code.
}

1 个答案:

答案 0 :(得分:5)

添加“,1” 缓冲区通道。这意味着对通道的一次写入是非阻塞的,并且主程序保留了控制权。如果未缓冲通道,则写入程序将阻塞,直到另一个goroutine获得控制并从该通道读取为止。

程序已将字符串放入缓冲的通道;它现在继续运行,从缓冲的通道中读取字符串,然后打印它,而从未阻塞。

如果您使用goroutine和无缓冲通道:

  • goroutine启动,从通道读取并阻塞,等待将某些内容写入通道。
  • 主程序写入通道和块,等待有人读取刚刚写入的字符串。
  • Go调度程序查找有资格运行的例程,找到带有准备从通道读取的字符串的goroutine。它将控制权返回给goroutine,goroutine接收字符串并继续。
  • 当该goroutine退出或执行其他操作使其失去控制时,调度程序将寻找另一个可以运行的程序,并看到主程序已成功完成对通道的写入(goroutine已读取该字符串)。调度程序将控制权交给主程序。
  • 主程序完成并退出。