我搞不懂为什么这段代码会死锁.我收到了一个关于猩猩睡着的致命错误.我使用一个等待组来同步并等待Goroutines完成,同时传递我创建的一个等待组的地址,而不是复制.我试着用和不用缓冲器,但仍然.

package main

import (
    "fmt"
    "sync"
)


func findMax(nums []int32) int32{
    max:=nums[0]
    for _, n := range nums{
        if n > max{
            max = n
        }
    }
    return max
}

func findFreq(nums []int32,  n int32) int32{
    mp := make(map[int32]int32)
    for _, num := range nums{
        if _, ok := mp[num]; ok{
            mp[num]+=1
        }else{
            mp[num]=1
        }
    }
    if f, ok := mp[n]; ok{
        return f
    }else{
        return -1
    }
}

func performWork(ch chan int32, nums []int32, q int32, wg *sync.WaitGroup){
    defer wg.Done()
    seg:=nums[q-1:]
    max:=findMax(seg)
    freq:=findFreq(seg, max)
    ch <- freq
}

func frequencyOfMaxValue(numbers []int32, q []int32) []int32 {
    res := []int32{}
    var wg sync.WaitGroup
    ch := make(chan int32)
    
    for _, query := range q{
        wg.Add(1)
        go performWork(ch, numbers, query, &wg)
    }
    wg.Wait()
    for n := range ch{
        res=append(res, n)
    }
    return res

}
func main() {
  nums := []int32{5,4,5,3,2}
  queries:=[]int32{1,2,3,4,5}
  fmt.Println(frequencyOfMaxValue(nums,queries))
}

推荐答案

工人们被封锁,等待主要的大猩猩在海峡上接收.主要的大猩猩路由被封锁,等待工人们完成.僵持!

假设你克服了这一僵局,那么又会有另一场僵局.主要的Goroutine在一个循环中收到ch,但没有任何东西接近ch.

当工作进程完成时,通过运行另一个Goroutine来关闭通道,从而消除死锁.

for _, query := range q {
    wg.Add(1)
    go performWork(ch, numbers, query, &wg)
}

go func() {
    wg.Wait() // <-- wait for workers
    close(ch) // <-- causes main to break of range on ch.
}()

for n := range ch {
    res = append(res, n)
}

Go相关问答推荐

如何模拟嵌入. FS?

如何在jsonrpc服务器的服务器端捕获错误?

使用一元或服务器流将切片从GRPC服务器返回到客户端

我找不到pcap.Openlive的设备名称

在Go中旋转矩阵

从文件读取字节,将其保存到 struct 体并修改值

如何创建在responseWriter.Write 上返回错误的http.ResponseWriter 模拟实例?

Go 中的sync.Cond 与 Wait 方法

htmx 表单 + gin 无法正确读取请求正文

如何将 base64 编码的公钥转换为 crypto.PublicKey 或 ecdsa.PublicKey

接受通道和切片的通用函数

如何使用带有方法的字符串枚举作为通用参数?

如何使用 fyne Go 使用 canvas.NewText() 使文本可滚动

不能在 *gorm.db 而不是 gorm.db 上使用 WithContext(ctx) 方法

有没有办法将 yaml node 添加到 golang 中现有的 yaml 文档中?

如何通过组合来自不同包的接口来创建接口?

Unescape 在 rss 中两次逃脱了标题

如何排除溢出矩阵的坐标

GORM GIN 更新查询导致 500 内部服务器错误

我该如何做错误处理惯用的方式