1 回答
TA贡献1785条经验 获得超4个赞
这段代码有问题
for {
select {
case x := <- events.Publish:
fmt.Println(x)
default:
fmt.Println("waiting for data ...")
time.Sleep((time.Duration(math.MaxInt64)))
}
}
当select被调用并假设Publish通道仍然为空时,默认情况将运行并使用该time.Sleep语句永远阻塞主循环。因此,即使Publish通道从另一个 go-routine 接收数据,主 go-routine 仍然停留在该 Sleep 语句上。
任何时候你想将定时等待与通道事件结合起来,你可以这样做:
timerChannel := time.NewTimer(duration)
select {
case <-timerChannel.C:
{
// time out
}
case x := <-events.Publish:
{
fmt.println(x)
}
}
但是由于您的意图似乎只是阻止main退出,所以它更简单:
for {
x := <- events.Publish: // blocks until Publish channel has data
fmt.Println(x)
}
但是正如你所说的那样,这会导致僵局,因为在你的三个 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
}
}
}
}
正如评论中所讨论的,需要初始化通道,缺少make,必须按以下方式完成:
package events
import "sync"
var (
Wg sync.WaitGroup
Publish chan string
)
func init() {
Publish = make(chan string)
}
- 1 回答
- 0 关注
- 106 浏览
添加回答
举报