去渠道准备
Go channel readyness
我想了解 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 routine 成功传递到主程序。是什么让这个计划奏效?为什么第二个有效但第一个无效? go routine 会造成一些差异吗?
让我们逐步完成第一个程序:
// My notes here
ch := make(chan int) // make a new int channel
ch <- 1 // block until we can send to that channel
// keep blocking
// keep blocking
// still waiting for a receiver
// no reason to stop blocking yet...
// this line is never reached, because it blocks above forever.
fmt.Println(<-ch)
第二个程序将发送拆分到它自己的执行行中,所以现在我们有:
ch := make(chan int) // make a new int channel
go func () { // start a new line of execution
ch <- 1 // block this second execution thread until we can send to that channel
}()
fmt.Println(<-ch) // block the main line of execution until we can read from that channel
由于这两条执行线可以独立工作,主线可以下到 fmt.Println
并尝试从频道接收。第二个线程将等待发送直到发送。
go 例程绝对不同。写入通道的 go 例程将被阻塞,直到您的主函数准备好从 print 语句中的通道读取。有两个并发线程,一个读取一个写入,满足双方的准备。
在您的第一个示例中,单个线程被通道写入语句阻塞,永远不会到达通道读取。
您需要有一个并发的 go 例程,以便在您写入通道时从通道读取。并发性 hand-in-hand 随通道使用而变化。
我想了解 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 routine 成功传递到主程序。是什么让这个计划奏效?为什么第二个有效但第一个无效? go routine 会造成一些差异吗?
让我们逐步完成第一个程序:
// My notes here
ch := make(chan int) // make a new int channel
ch <- 1 // block until we can send to that channel
// keep blocking
// keep blocking
// still waiting for a receiver
// no reason to stop blocking yet...
// this line is never reached, because it blocks above forever.
fmt.Println(<-ch)
第二个程序将发送拆分到它自己的执行行中,所以现在我们有:
ch := make(chan int) // make a new int channel
go func () { // start a new line of execution
ch <- 1 // block this second execution thread until we can send to that channel
}()
fmt.Println(<-ch) // block the main line of execution until we can read from that channel
由于这两条执行线可以独立工作,主线可以下到 fmt.Println
并尝试从频道接收。第二个线程将等待发送直到发送。
go 例程绝对不同。写入通道的 go 例程将被阻塞,直到您的主函数准备好从 print 语句中的通道读取。有两个并发线程,一个读取一个写入,满足双方的准备。
在您的第一个示例中,单个线程被通道写入语句阻塞,永远不会到达通道读取。
您需要有一个并发的 go 例程,以便在您写入通道时从通道读取。并发性 hand-in-hand 随通道使用而变化。