【发布时间】:2021-08-26 08:30:17
【问题描述】:
以下是代码:
func makeData() map[string][]Data {
m := make(map[string][]Data)
s := "abcdefghijklmno"
for i, c := range s {
data := []Data{
{value: "hey_" + string(c), id: i * i},
{value: "hello_" + string(c) + string(c), id: i + i},
{value: "bye_" + string(c), id: i + 1},
}
m[strconv.Itoa(i)] = data
}
return m
}
func process(key string, value []Data) (*Result, error) {
if key == "hey_a" {
return nil, errors.New("error")
}
res := Result{data: Data{value: "hi", id: 0}, id: 1}
return &res, nil
}
func main() {
runtime.GOMAXPROCS(runtime.NumCPU())
m := makeData()
errg := new(errgroup.Group)
mapChan := make(chan StringAndData)
sliceChan := make(chan *Result)
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)
for ac := range mapChan {
fmt.Println(ac.str)
}
}
type Data struct {
value string
id int
}
type Result struct {
data Data
id int
}
type StringAndData struct {
str string
data Data
}
我收到了fatal error: all goroutines are asleep - deadlock!,但我在errg.Wait() 之后关闭了频道,我无法理解原因。
我正在尝试打印使用range 关闭通道后从通道获得的值。
我是 go 的通道和并发新手,希望能提供任何帮助!
编辑 添加了游乐场链接中的所有代码
【问题讨论】:
-
m和errg来自哪里?请发布最小的、可重现的示例。 -
@jub0bs 请查看操场链接。是
errorGroup -
那是最小的吗?此外,SO 问题应该是独立的。
-
@jub0bs 更新了更多代码
-
基本上这意味着当
errg.Wait()完成时,仍有未完成的goroutines(等待一些资源)。 Go 检测到所有这些 goroutine(包括等待mapChan的 main)在某些资源上被阻塞。首先要做的是放弃使用errgroup:在您对基本知识感到满意之前,请不要陷入使用花哨东西的陷阱。使用普通通道使您的代码工作(可能是sync.WaitGroup)。
标签: go concurrency deadlock channel