1 回答

TA貢獻2011條經(jīng)驗 獲得超2個贊
您正在使用一個無緩沖的通道,它作為主 goroutine 和第二個 goroutine 之間的同步點。
在這種情況下,你只知道當?shù)诙€ goroutine 在這里時,messages <- "ping1"主要的 goroutine 在 line 上for msg := range messages。因此,不能保證主循環(huán)println(msg)立即到達。也就是說,與此同時,第二個 goroutine 可以繼續(xù)前進并到達 lines println("p2")and messages <- "ping2"。
作為一個反例,我添加一個通道只是為了強制打印之間的完全同步。
package main
func rtn(messages chan<- string, syncChan chan struct{}) {
defer close(messages)
println("p1")
messages <- "ping1"
//Wait for main goroutine to print its message
<-syncChan
//for i := 0; i < 10000000; i++ { }
println("p2")
messages <- "ping2"
//Wait for main goroutine to print its message
<-syncChan
}
func main() {
messages := make(chan string)
syncChan := make(chan struct{})
go rtn(messages, syncChan)
for msg := range messages {
println(msg)
//Notify the second goroutine that is free to go
syncChan <- struct{}{}
}
}
打印出您期望的輸出:
p1
ping1
p2
ping2
這是另一個產(chǎn)生您正在尋找的輸出的示例。在這種情況下,主 goroutine 被time.Sleep(). 這將使第二個 goroutine 在接收器準備好接收之前準備好發(fā)送。因此,發(fā)送方實際上會阻塞發(fā)送操作。
package main
import (
"time"
)
func rtn(messages chan<- string) {
defer close(messages)
println("p1")
messages <- "ping1"
//for i := 0; i < 10000000; i++ { }
println("p2")
messages <- "ping2"
}
func main() {
messages := make(chan string)
go rtn(messages)
//Put main goroutine to sleep. This will make the
//sender goroutine ready before the receiver.
//Therefore it will have to actually block!
time.Sleep(time.Millisecond * 500)
for msg := range messages {
println(msg)
}
}
- 1 回答
- 0 關注
- 154 瀏覽
添加回答
舉報