首页 > 后端开发 > Golang > 陷入死锁:为什么会发生'抛出:所有 goroutine 都在睡觉”?

陷入死锁:为什么会发生'抛出:所有 goroutine 都在睡觉”?

Mary-Kate Olsen
发布: 2025-01-02 15:03:39
原创
558 人浏览过

Go Deadlock: Why Does

Go 中的死锁:“抛出:所有 goroutine 都在睡眠”

Go 程序中,当两个或多个 goroutine 等待时,就会发生死锁彼此完成,导致冻结状态,无法取得任何进展。这个问题经常被报告为“抛出:所有 goroutine 都在睡眠 - 死锁!”

让我们分析一个简化的 Go 程序来理解为什么会发生这种死锁:

package main

import (
    "fmt"
)

func total(ch chan int) {
    res := 0
    for iter := range ch {
        res += iter
    }
    ch <- res
}

func main() {
    ch := make(chan int)
    go total(ch)
    ch <- 1
    ch <- 2
    ch <- 3
    fmt.Println("Total is ", <-ch)
}
登录后复制

在这个程序中, Total 函数计算通过 ch 通道发送的数字的总和,并将结果发送回同一通道。出现死锁是因为满足以下条件:

  • for 循环内的总函数块等待通过 ch 进行更多输入(带有 range 关键字)。
  • main 函数发送向 ch 发送三个值,但不会关闭通道。
  • 由于 Total 函数仍在等待更多输入,因此不会将结果发送回ch.
  • main 函数在 fmt.Println 行阻塞,等待 ch.

这会产生死锁情况,两个 goroutine(一个运行总计和一个) in main) 正在等待对方采取行动,导致“抛出:所有 goroutine 都在睡眠”错误。

解决此问题死锁,我们可以在发送最后一个值后关闭 main 函数中的 ch 通道:

ch <- 3
close(ch)
登录后复制

关闭通道向总 goroutine 发出信号,表明没有更多输入,允许其完成计算并发送结果返回到ch.

以上是陷入死锁:为什么会发生'抛出:所有 goroutine 都在睡觉”?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板