1 回答
TA贡献1801条经验 获得超8个赞
查看代码,有两件事可能会导致死锁:
errg.Wait()
阻止主 goroutine 的执行,直到所有初始化的 goroutine 都完成。但是,在尝试写入 时,每个 goroutine 都会被阻止,因为您永远无法从中读取(因为它位于 )。mapChan
errg.Wait()
你从来没有读过,所以这是一个潜在的死锁。
sliceChan
以下是修改后的 Playground 代码的链接,但大多数更改都在函数中。main
func main() {
runtime.GOMAXPROCS(runtime.NumCPU())
m := makeData()
errg := new(errgroup.Group)
mapChan := make(chan StringAndData)
sliceChan := make(chan *Result)
mapDone := make(chan bool)
sliceDone := make(chan bool)
go func(){
for ac := range mapChan {
fmt.Println(ac.str)
}
mapDone <- true
}()
go func(){
for ac := range sliceChan {
fmt.Println(ac)
}
sliceDone <- true
}()
for key, value := range m {
key := key
value := value
errg.Go(func() error {
return func(key string, value []Data) error {
res, err := process(key, value)
if err != nil {
return err
}
if res == nil {
return nil
}
if res.data.id == 1 {
mapChan <- StringAndData{
str: key,
data: res.data,
}
return nil
}
sliceChan <- res
return nil
}(key, value)
})
}
if err := errg.Wait(); err != nil {
fmt.Println("error")
} else {
fmt.Println("success")
}
close(mapChan)
close(sliceChan)
<-mapDone
<-sliceDone
fmt.Println("finished")
}
基本上,我更改了从中读取值和通道的方式。这是在单独的goroutines中完成的,因此不会阻止从这些通道读取。mapChansliceChan
添加 和 通道只是为了确保在 goroutine 完成之前读取所有数据。mapDonesliceDonemain
- 1 回答
- 0 关注
- 97 浏览
添加回答
举报