0{"/> 0{">
Home >Backend Development >Golang >Fatal error: all goroutines are sleeping - deadlock! Error execution
#php editor Strawberry will introduce you to a common programming error in this article: Fatal error: "All goroutines are sleeping - deadlock! Error execution". This is one of the common mistakes in the Go language and one of the challenges that developers often encounter. In this article, we will explain the cause and solution of this error in detail to help everyone better understand and deal with this problem. Whether you are a beginner or an experienced developer, you will get valuable information and tips from this article. Let’s explore together!
I am very new to concurrency in go, so I tried an example with channels and goroutines. I want the producer-consumer model. The producer function always gives random strings and the consumer modifies them by making them uppercase. I want to run it for a limited time (2 seconds).
package main import ( "fmt" "math/rand" "strings" "time" ) func producer(x []string, c chan string) { i := 1 for i > 0 { randomIndex := rand.Intn(len(x)) pick := x[randomIndex] c <- pick } } func consumer(x string, c chan string) { x1 := strings.ToUpper(x) c <- x1 } func main() { s := []string{"one", "two", "three", "four"} c1 := make(chan string) d1 := make(chan string) go producer(s, c1) go consumer(<-c1, d1) stop := time.After(2000 * time.Millisecond) for { select { case <-stop: fmt.Println("STOP AFTER 2 SEC!") return default: fmt.Println(<-d1) time.Sleep(50 * time.Millisecond) } } }
I only receive one array element and some errors. What changes need to be made to make this example work?
Output:
two
Fatal error: All goroutines are sleeping - deadlock!
goroutine 1 [chan receive]: main.main()
Coroutine 6 [chan send]: main.producer({0xc00004e040, 0x4, 0x0?}, 0x0?) Created by main. main Exit Status 2
Your consumer should run in a loop, this has already been mentioned.
Change the first parameter of consumer so that it is chan string
instead of a string. This way the producer can keep writing to this channel for the consumer to publish on another channel until the time limit expires.
func consumer(consumechan chan string, outch chan string) { for { select { case s := <- consumechan: s = strings.toupper(s) outch <- s } } }
Now, in the main function before calling go consumer()
, you are waiting for the first response from the producer on the c1
channel. Don't do this, instead pass the c1
channel as the first argument.
func main() { s := []string{"one", "two", "three", "four"} c1 := make(chan string) d1 := make(chan string) go producer(s, c1) go consumer(c1, d1) stop := time.After(2000 * time.Millisecond) for { select { case <-stop: fmt.Println("STOP AFTER 2 SEC!") return case response := <- d1: fmt.Println(response) time.Sleep(50 * time.Millisecond) } } }
This should show the producer continuously writing random numbers on the c1
channel, and the consumer continuously writing all uppercase text on the d1 channel until the 2 seconds are up.
The above is the detailed content of Fatal error: all goroutines are sleeping - deadlock! Error execution. For more information, please follow other related articles on the PHP Chinese website!