ibeautiful
2023-07-17 16:54:58
代碼: https: //play.golang.org/p/Oh3oTa7GIPXtype a struct { c chan bool}func (a *a) do() { a.c <- true}type b struct { c chan bool a a}func main() { b := b{ c: make(chan bool), a: a{c: make(chan bool)}, } go b.s() b.c <- true // below is to stay main gorutine alive done := make(chan bool) go func() { time.Sleep(10 * time.Second) done <- true }() for { select { case <-done: fmt.Println("Done!") return } }}func (b *b) s() { for { select { case <-b.c: fmt.Println("b c") b.a.do() case <-b.a.c: fmt.Println("b a c") } }}上述實際輸出是b cDone!預期輸出:b cb a cDone !我不明白為什么它不打印b a c?代碼是不言自明的,如果還需要更多詳細信息,請詢問
1 回答

楊魅力
TA貢獻1811條經驗 獲得超6個贊
你的maingoroutine 在 上發送一個值b.c,然后等待:
b.c <- true
從 main 啟動的 goroutine:
go b.s()
這是從 接收的b.c,也是從 接收的b.a.c:
func (b *b) s() {
for {
select {
case <-b.c:
fmt.Println("b c")
b.a.do()
case <-b.a.c:
fmt.Println("b a c")
}
}
}
如果從 接收到一個值b.c,則該 goroutine 會嘗試發送b.a.c(在a.do()方法中),并且您希望同一個goroutine 從 接收b.a.c。但由于b.a.c是無緩沖的,發送將被阻塞,因此它永遠不會到達b.s()它可以/將從中接收的下一個迭代b.a.c。
如果一個通道是無緩沖的,那么只有當有另一個 goroutine 準備從它接收數據時,才可以在該通道上進行發送。
如果您對b.a.c通道進行緩沖,則可以在不阻塞的情況下繼續發送,因此在下一次迭代中可以接收它:
a: a{c: make(chan bool, 1)}
通過此更改,您將獲得預期的輸出。在Go Playground上嘗試一下。
- 1 回答
- 0 關注
- 145 瀏覽
添加回答
舉報
0/150
提交
取消