2 回答

TA貢獻(xiàn)1795條經(jīng)驗(yàn) 獲得超7個(gè)贊
該代碼邏輯有許多缺陷 - 其中一些是:
1- 由于messageCh被緩沖,此代碼沒有阻塞:
for i := 0; i < 10; i++ {
messageCh <- i
}
所以下一個(gè)代碼在快速運(yùn)行路徑中:
disconnectCh <- struct{}{}
如果您進(jìn)行disconnectCh緩沖,則此行也不會(huì)阻塞運(yùn)行,并且該SelectDemo函數(shù)可能會(huì)在運(yùn)行wg.Add(1).
所以:你必須把:
wg.Add(1)
前
go func() {
2-即使使用wg.Add(1)之前的go func() { 代碼-
您也有:
defer close(messageCh)
defer close(disconnectCh)
這將在函數(shù)返回時(shí)關(guān)閉兩個(gè)通道SelectDemo這select是一個(gè)隨機(jī)選擇,因?yàn)閮蓚€(gè)通道都準(zhǔn)備好了:
fmt.Println(" goroutine")
for {
select {
case v := <-messageCh:
fmt.Println(v)
case <-disconnectCh:
第二個(gè)選擇很可能是:
for {
select {
case v := <-messageCh:
fmt.Println(v)
default:
fmt.Println(" disconnection, return")
wg.Done()
return
}
}
將在messageCh關(guān)閉后0永遠(yuǎn)運(yùn)行,在讀取通道數(shù)據(jù)后永遠(yuǎn)返回:
case v := <-messageCh:
fmt.Println(v)

TA貢獻(xiàn)2080條經(jīng)驗(yàn) 獲得超4個(gè)贊
程序執(zhí)行速度快
訪問網(wǎng)址:https ://pkg.go.dev/sync#WaitGroup.Add
請(qǐng)注意,當(dāng)計(jì)數(shù)器為零時(shí)發(fā)生的具有正增量的調(diào)用必須在等待之前發(fā)生。具有負(fù)增量的調(diào)用或具有正增量的調(diào)用在計(jì)數(shù)器大于零時(shí)開始,可能隨時(shí)發(fā)生。通常這意味著對(duì) Add 的調(diào)用應(yīng)該在創(chuàng)建 goroutine 的語(yǔ)句或其他要等待的事件之前執(zhí)行。如果重用 WaitGroup 來等待多個(gè)獨(dú)立的事件集,則必須在所有先前的 Wait 調(diào)用都返回后發(fā)生新的 Add 調(diào)用。請(qǐng)參閱 WaitGroup 示例。
func SelectDemo(wg *sync.WaitGroup) {
messageCh := make(chan int, 10)
disconnectCh := make(chan struct{}, 1)
// go routine won't run if channel is buffered
//disconnectCh := make(chan struct{}, 1)
wg.Add(1)
defer close(messageCh)
defer close(disconnectCh)
go func() {
fmt.Println(" goroutine")
for {
select {
case v := <-messageCh:
fmt.Println(v)
case <-disconnectCh:
fmt.Println(" disconnectCh")
// empty the buffered channel before exiting
fmt.Println(" disconnection, return")
wg.Done()
return
}
}
}()
fmt.Println("Sending ints")
for i := 0; i < 10; i++ {
messageCh <- i
}
//Delay sending exit signal
time.Sleep(3 * time.Second)
fmt.Println("Sending done")
disconnectCh <- struct{}{}
}
我修改了你的代碼
再試一次?。?!
- 2 回答
- 0 關(guān)注
- 120 瀏覽
添加回答
舉報(bào)