去渠道准备

我想了解 Go 中的频道。我读过默认情况下发送和接收块,直到发送方和接收方都准备好。但是我们如何确定发送方和接收方的准备情况。


例如在下面的代码中


package main


import "fmt"


func main() {

    ch := make(chan int)

    ch <- 1


    fmt.Println(<-ch)

}

该程序将卡在通道发送操作上,永远等待有人读取值。即使我们在 println 语句中有一个接收操作,它也会以死锁结束。


但是对于下面的程序


package main


import "fmt"


func main() {

    ch := make(chan int)


    go func () {

        ch <- 1

    }()


    fmt.Println(<-ch)

}

整数从 go 例程成功传递到主程序。是什么让这个计划奏效?为什么第二个有效但第一个无效?go routine 会造成一些差异吗?


Helenr
浏览 91回答 2
2回答

LEATH

让我们逐步完成第一个程序:// My notes herech := make(chan int)&nbsp; // make a new int channelch <- 1&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// block until we can send to that channel&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // keep blocking&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // keep blocking&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // still waiting for a receiver&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // no reason to stop blocking yet...// this line is never reached, because it blocks above forever.fmt.Println(<-ch)第二个程序将发送拆分到它自己的执行行中,所以现在我们有:ch := make(chan int)&nbsp; // make a new int channelgo func () {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // start a new line of execution&nbsp; &nbsp; ch <- 1&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// block this second execution thread until we can send to that channel}()fmt.Println(<-ch)&nbsp; &nbsp; &nbsp;// block the main line of execution until we can read from that channel由于这两条执行线可以独立工作,因此主线可以下到通道fmt.Println并尝试从通道接收。第二个线程将等待发送直到发送完毕。

九州编程

go 例程绝对有所作为。写入通道的 go 例程将被阻塞,直到您的主函数准备好从 print 语句中的通道读取。有两个并发线程,一个读取,一个写入,满足双方的准备工作。在您的第一个示例中,单个线程被通道写入语句阻塞,并且永远不会到达通道读取。您需要有一个并发的 go 例程,以便在您写入通道时从通道中读取。并发与通道使用密切相关。
打开App,查看更多内容
随时随地看视频慕课网APP