1 回答

TA貢獻(xiàn)1801條經(jīng)驗(yàn) 獲得超8個(gè)贊
查看代碼,有兩件事可能會(huì)導(dǎo)致死鎖:
errg.Wait()
阻止主 goroutine 的執(zhí)行,直到所有初始化的 goroutine 都完成。但是,在嘗試寫(xiě)入 時(shí),每個(gè) goroutine 都會(huì)被阻止,因?yàn)槟肋h(yuǎn)無(wú)法從中讀取(因?yàn)樗挥?)。mapChan
errg.Wait()
你從來(lái)沒(méi)有讀過(guò),所以這是一個(gè)潛在的死鎖。
sliceChan
以下是修改后的 Playground 代碼的鏈接,但大多數(shù)更改都在函數(shù)中。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")
}
基本上,我更改了從中讀取值和通道的方式。這是在單獨(dú)的goroutines中完成的,因此不會(huì)阻止從這些通道讀取。mapChansliceChan
添加 和 通道只是為了確保在 goroutine 完成之前讀取所有數(shù)據(jù)。mapDonesliceDonemain
- 1 回答
- 0 關(guān)注
- 125 瀏覽
添加回答
舉報(bào)