【问题标题】:Channel send and receive on func main()func main() 上的通道发送和接收
【发布时间】:2018-12-19 00:22:42
【问题描述】:

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

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

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

为什么上面会导致错误?我知道我可以通过引入一个 goroutine 让发送者和接收者都准备好来使它工作。但是,如果是这样,为什么以下工作。

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

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

}

*********感谢乔·麦克马洪的回答*********
*********下面记录供我参考*********
我假设缓冲区 1(与 2 不同)也会阻塞主程序,直到找到相应的接收器。看起来 1 的缓冲区就像 0 和 1 一样工作,并且不会阻止第 0 次写入/读取的代码。为了演示使用缓冲区的块,

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

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

【问题讨论】:

标签: go


【解决方案1】:

添加 ',1' 缓冲区 通道。这意味着对通道的一次写入是非阻塞的,并且主程序保留控制权。如果通道没有缓冲,那么写入程序会阻塞,直到另一个 goroutine 获得控制并从通道中读取。

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

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

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

【讨论】:

    猜你喜欢
    • 2015-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多