1 回答

TA貢獻(xiàn)1785條經(jīng)驗(yàn) 獲得超4個(gè)贊
這段代碼有問題
for {
select {
case x := <- events.Publish:
fmt.Println(x)
default:
fmt.Println("waiting for data ...")
time.Sleep((time.Duration(math.MaxInt64)))
}
}
當(dāng)select被調(diào)用并假設(shè)Publish通道仍然為空時(shí),默認(rèn)情況將運(yùn)行并使用該time.Sleep語(yǔ)句永遠(yuǎn)阻塞主循環(huán)。因此,即使Publish通道從另一個(gè) go-routine 接收數(shù)據(jù),主 go-routine 仍然停留在該 Sleep 語(yǔ)句上。
任何時(shí)候你想將定時(shí)等待與通道事件結(jié)合起來(lái),你可以這樣做:
timerChannel := time.NewTimer(duration)
select {
case <-timerChannel.C:
{
// time out
}
case x := <-events.Publish:
{
fmt.println(x)
}
}
但是由于您的意圖似乎只是阻止main退出,所以它更簡(jiǎn)單:
for {
x := <- events.Publish: // blocks until Publish channel has data
fmt.Println(x)
}
但是正如你所說的那樣,這會(huì)導(dǎo)致僵局,因?yàn)樵谀愕娜齻€(gè) go-routines 退出后,就沒有什么可做的了。
快速解決:
func main() {
fmt.Println("Starting")
events.Wg.Add(1)
go events.User.Trigger("new", "Hasan")
events.Wg.Add(1)
go events.User.Trigger("name", []any{"Hasan", "Ali"})
events.Wg.Add(1)
go events.User.Trigger("new", "Ali")
exitChannel := make(chan bool)
go func() {
events.Wg.Wait()
close(exitChannel)
}()
canExit := false
for !canExit {
select {
case x := <-events.Publish:
{
fmt.Println(x)
}
case <- exitChannel:
{
canExit = true
}
}
}
}
正如評(píng)論中所討論的,需要初始化通道,缺少make,必須按以下方式完成:
package events
import "sync"
var (
Wg sync.WaitGroup
Publish chan string
)
func init() {
Publish = make(chan string)
}
- 1 回答
- 0 關(guān)注
- 130 瀏覽
添加回答
舉報(bào)