Go Program deadlock: "throw: all goroutines are asleep"
In a Go program, a deadlock occurs when two or more goroutines (concurrently running functions) wait indefinitely for each other to complete. One such situation can arise when working with channels, as seen in the following program:
package main import ( "fmt" ) func total(ch chan int) { res := 0 for iter := range ch { res += iter } ch <- res } func main() { ch := make(chan int) go total(ch) ch <- 1 ch <- 2 ch <- 3 fmt.Println("Total is ", <-ch) }
Running this program will result in the panic message:
throw: all goroutines are asleep - deadlock!
The root cause of this deadlock lies in the fact that the total goroutine attempts to send a value back to the same channel it's receiving from (ch). Because the channel is not closed (signaling completion), the range loop in the total goroutine will continue indefinitely, blocking any further sends or receives.
To fix this issue, we can introduce another channel to receive the result. Here's an updated program:
package main import ( "fmt" ) func total(in chan int, out chan int) { res := 0 for iter := range in { res += iter } out <- res // Send result on separate channel } func main() { ch := make(chan int) rch := make(chan int) // New channel to receive result go total(ch, rch) ch <- 1 ch <- 2 ch <- 3 close(ch) // Explicitly close channel to end loop in `total` result := <-rch // Wait for result on `rch` fmt.Println("Total is ", result) }
By sending the result on a separate channel and closing the original channel, we break the deadlock and allow the main goroutine to receive the calculated total.
The above is the detailed content of Why Does My Go Program Deadlock with the 'all goroutines are asleep' Error?. For more information, please follow other related articles on the PHP Chinese website!