Home >Backend Development >Golang >How to Resolve \'Fatal Error: All Goroutines Are Asleep - Deadlock!\' in Go When Using Unbuffered Channels?

How to Resolve \'Fatal Error: All Goroutines Are Asleep - Deadlock!\' in Go When Using Unbuffered Channels?

Barbara Streisand
Barbara StreisandOriginal
2024-11-25 15:36:17714browse

 How to Resolve

"Go: Fatal Error: All Goroutines Are Asleep - Deadlock"

Problem:

You have a text file with a single line of words and you're attempting to store each word in a channel. Subsequently, you want to retrieve these words from the channel and print them one at a time. The following code snippet represents your current approach:

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

However, upon running this code, you encounter the error message: "fatal error: all goroutines are asleep - deadlock!"

Solution:

The error arises because your file1chan is an unbuffered channel. When you attempt to send a value down this channel, it blocks indefinitely, waiting for a receiver. To resolve this deadlock, you can either start a new goroutine responsible for sending values into the channel or declare the channel as buffered. Two approaches are outlined below:

Using a New 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)
    }
}

Using a Buffered Channel:

For handling a single string, you can define a buffered channel of size 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)
    }
}

The above is the detailed content of How to Resolve \'Fatal Error: All Goroutines Are Asleep - Deadlock!\' in Go When Using Unbuffered Channels?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn