首页 > 后端开发 > Golang > 为什么我的 Go 程序会死锁并出现'all goroutine are sleep”错误?

为什么我的 Go 程序会死锁并出现'all goroutine are sleep”错误?

DDD
发布: 2024-12-23 02:11:14
原创
905 人浏览过

Why Does My Go Program Deadlock with the

Go 程序死锁:“抛出:所有 goroutine 都在睡眠”

在 Go 程序中,当两个或多个 goroutine (并发运行的函数)无限期地等待彼此完成。使用通道时可能会出现一种这样的情况,如以下程序所示:

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)
}
登录后复制

运行此程序将导致恐慌消息:

throw: all goroutines are asleep - deadlock!
登录后复制

此问题的根本原因死锁在于这样一个事实:总 goroutine 尝试将一个值发送回它从 (ch) 接收的同一通道。由于通道未关闭(发出完成信号),整个 goroutine 中的范围循环将无限期地继续下去,从而阻塞任何进一步的发送或接收。

要解决此问题,我们可以引入另一个通道来接收结果。这是一个更新的程序:

package main

import (
    "fmt"
)

func total(in chan int, out chan int) {
    res := 0
    for iter := range in {
        res += iter
    }
    out <- res // Send result on separate channel
}

func main() {
    ch := make(chan int)
    rch := make(chan int) // New channel to receive result
    go total(ch, rch)
    ch <- 1
    ch <- 2
    ch <- 3
    close(ch) // Explicitly close channel to end loop in `total`
    result := <-rch // Wait for result on `rch`
    fmt.Println("Total is ", result)
}
登录后复制

通过在单独的通道上发送结果并关闭原始通道,我们打破了僵局并允许主 goroutine 接收计算出的总数。

以上是为什么我的 Go 程序会死锁并出现'all goroutine are sleep”错误?的详细内容。更多信息请关注PHP中文网其他相关文章!

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