首页 > 后端开发 > Golang > 为什么 Go 程序会遇到'致命错误:所有 goroutine 都在睡眠 - 死锁!”以及如何修复?

为什么 Go 程序会遇到'致命错误:所有 goroutine 都在睡眠 - 死锁!”以及如何修复?

Patricia Arquette
发布: 2024-11-17 02:23:03
原创
245 人浏览过

Why do Go programs encounter the

Go:死锁恐慌 - 了解原因并修复它

在 Go 中,遇到的常见错误是“致命错误:所有 goroutine 都睡着了——僵局!”当尝试管理 goroutine 之间的通信时。当 goroutine 陷入相互等待对方继续的状态时,就会出现此错误。

问题陈述

考虑以下您想要阅读的代码文本文件中的一行单词,将它们存储在通道中,然后打印它们分别:

func main() {
    f, _ := os.Open("D:\input1.txt")
    scanner := bufio.NewScanner(f)
    file1chan := make(chan string)
    for scanner.Scan() {
        line := scanner.Text()
        parts := strings.Fields(line)
        for i := range parts {
            file1chan <- parts[i]
        }
    }
    print(file1chan)
}

func print(in <-chan string) {
    for str := range in {
        fmt.Printf("%s\n", str)
    }
}
登录后复制

死锁的原因

运行此代码时,您会遇到死锁错误。出现这种情况是因为通道 file1chan 未缓冲。因此,当您尝试将值发送到通道时,它会无限期地阻塞,等待接收者。

修复死锁

要解决死锁,你有两个选择:

  1. 使用缓冲通道:
    您可以通过将其大小指定为 make(chan) 的第二个参数来创建缓冲通道,如下所示:

    file1chan := make(chan string, 1) // buffer size of one
    登录后复制

    缓冲通道的作用类似于数组,其中如果通道有可用容量,发送者可以无阻塞地发送值。

  2. 使用新的Goroutine:
    你可以启动一个新的goroutine来向无缓冲的通道发送值:

    file1chan := make(chan string)
    go func() { // start a new goroutine that sends strings down file1chan
        for scanner.Scan() {
            line := scanner.Text()
            parts := strings.Fields(line)
            for i := range parts {
                file1chan <- parts[i]
            }
        }
        close(file1chan)
    }()
    
    print(file1chan)
    登录后复制

    通过这种方式,新的goroutine承担发送值的责任,而主goroutine则专注于

通过实施这些解决方案中的任何一个,您可以有效地消除僵局并使您的 goroutine 之间能够顺利通信。

以上是为什么 Go 程序会遇到'致命错误:所有 goroutine 都在睡眠 - 死锁!”以及如何修复?的详细内容。更多信息请关注PHP中文网其他相关文章!

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