首页 >后端开发 >Golang >Go中使用无缓冲通道时如何解决'致命错误:所有 Goroutine 都处于睡眠状态 - 死锁!”?

Go中使用无缓冲通道时如何解决'致命错误:所有 Goroutine 都处于睡眠状态 - 死锁!”?

Barbara Streisand
Barbara Streisand原创
2024-11-25 15:36:17705浏览

 How to Resolve

“Go:致命错误:所有 Goroutines 都处于睡眠状态 - 死锁”

问题:

您有一个包含一行单词的文本文件,并且您正在尝试将每个单词存储在一个通道中。随后,您希望从通道中检索这些单词并一次打印一个。以下代码片段代表您当前的方法:

package main

import (
    "bufio"
    "fmt"
    "os"
)

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)
    }
}

但是,在运行此代码时,您会遇到错误消息:“致命错误:所有 goroutine 都在睡眠 - 死锁!”

解决方案:

出现错误是因为你的file1chan是一个无缓冲的通道。当您尝试沿此通道发送值时,它会无限期地阻塞,等待接收者。要解决此死锁,您可以启动一个新的 goroutine 负责将值发送到通道中,或者将通道声明为缓冲通道。下面概述了两种方法:

使用新 Goroutine:

package main

import (
    "bufio"
    "fmt"
    "os"
)

func main() {
    f, _ := os.Open("D:\input1.txt")
    scanner := bufio.NewScanner(f)
    file1chan := make(chan string)

    // Start a new goroutine to send strings down file1chan
    go func() {
        for scanner.Scan() {
            line := scanner.Text()
            parts := strings.Fields(line)

            for i := range parts {
                file1chan <- parts[i]
            }
        }
        close(file1chan) // Close the channel when done sending.
    }()

    print(file1chan) // Read strings from file1chan
}

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

使用缓冲通道:

For处理单个字符串,您可以定义大小的缓冲通道1:

package main

import (
    "bufio"
    "fmt"
    "os"
)

func main() {
    f, _ := os.Open("D:\input1.txt")
    scanner := bufio.NewScanner(f)
    file1chan := make(chan string, 1) // Buffer size of one

    for scanner.Scan() {
        line := scanner.Text()
        parts := strings.Fields(line)

        for i := range parts {
            file1chan <- parts[i]
        }
    }

    close(file1chan) // Close the channel when done sending.
    print(file1chan)
}

func print(in <-chan string) {
    for str := range in { // Read all values until channel gets closed
        fmt.Printf("%s\n", str)
    }
}

以上是Go中使用无缓冲通道时如何解决'致命错误:所有 Goroutine 都处于睡眠状态 - 死锁!”?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn