使用 channel 时 goroutines 死锁

标签 go parallel-processing goroutine

我是 go lang 的新手,我正在尝试编写一个使用 goroutine 的简单递归算法。我正在使用 channel 从 goroutine 接收输出,但是当我尝试这样做时,我收到“ fatal error :所有 goroutines 都睡着了 - 死锁!”错误。如果我注释掉 channel 代码,一切都运行良好。 这是我的代码:

package main

import (
    "fmt"
    "sync"
)

func main() {
    numbers := []int{2, -1, 10, 4, 3, 6, 22}

    ch := make(chan []int)

    wg := &sync.WaitGroup{}
    wg.Add(1)
    go testFunc(numbers, ch, wg)
    wg.Wait()

    result := <-ch

    fmt.Println("Result: ", result)
}

func testFunc(numbers []int, ch chan []int, wg *sync.WaitGroup) {
    defer wg.Done()
    ch <- numbers
}

我做错了什么?我正在为 goroutine 中的 channel 分配值并在 main 中读取它。这还不够交流吗?

最佳答案

仅当发送方和接收方都准备就绪时,无缓冲 channel ch 上的通信才会成功。

主函数在接收值之前等待 WaitGroup 。 goroutine 尝试在调用 wg.Done 之前在 channel 上发送。这是一个僵局。

一个解决方法是使用缓冲 channel :

     ch := make(chan []int, 1)

另一个修复是在调用 wg.Wait() 之前在 channel 上接收。

result := <-ch
wg.Wait()

还有一个修复方法是删除所有使用 WaitGroup 的行。在这个特定示例中不需要它。

关于使用 channel 时 goroutines 死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47641514/

相关文章:

file - 使用golang将字节数组转换回文件

reflection - 使用反射包比较指针值

c# - 为什么并行多线程代码执行比顺序执行慢?

inheritance - 继承是 Go 中嵌入式结构的特例吗?

Golang gorilla 为 "//"URL 发送 301

haskell - 我可以得到 `cabal install` 来使用多核吗?

Perl:基于事件和基于并行的风格 - 何时选择一种?

go - 如何设计goroutines程序来处理api限制错误

go - 如何在 lambda 处理程序回复后等待 goroutine 完成

go - 扇出,多播,接收者数量未知