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