In this article, we'll analyze the causes behind the "deadlock!" error that arises from a deadlock situation involving Go channels in the following code snippet:
package main import ( "fmt" "sync" ) func push(c chan int, wg sync.WaitGroup) { for i := 0; i < 5; i++ { c <- i } wg.Done() } func pull(c chan int, wg sync.WaitGroup) { for i := 0; i < 5; i++ { result, ok := <-c fmt.Println(result, ok) } wg.Done() } func main() { var wg sync.WaitGroup wg.Add(2) c := make(chan int) go push(c, wg) go pull(c, wg) wg.Wait() }
When running this code, we encounter the following error:
throw: all goroutines are asleep - deadlock!
The deadlock occurs because structs, like the sync.WaitGroup in this code, are passed by value and not by reference. This means that when we pass the WaitGroup to our functions (push and pull), we are actually passing a copy of the WaitGroup instead of the original object.
As a result, each function is working on its own copy of the WaitGroup, and when they call wg.Done(), they are decrementing their own copies. This does not update the original WaitGroup, which is what our main goroutine is waiting on, thus leading to a deadlock.
To resolve this issue, we need to pass the pointer to the WaitGroup instead of the value. This will ensure that both the push and pull functions are working on the same instance of the WaitGroup, and their calls to wg.Done() will affect the original object.
Here's a corrected version of the code:
package main import ( "fmt" "sync" ) func push(c chan int, wg *sync.WaitGroup) { for i := 0; i < 5; i++ { c <- i } wg.Done() } func pull(c chan int, wg *sync.WaitGroup) { for i := 0; i < 5; i++ { result, ok := <-c fmt.Println(result, ok) } wg.Done() } func main() { var wg sync.WaitGroup wg.Add(2) c := make(chan int) go push(c, &wg) go pull(c, &wg) wg.Wait() }
By making this change, we now pass the pointer to the WaitGroup to our functions, ensuring that both of them are working on the same object and correctly updating its state. This eliminates the deadlock situation and allows our program to run without any errors.
The above is the detailed content of How to Fix Deadlock Errors in Go Channels When Using sync.WaitGroup?. For more information, please follow other related articles on the PHP Chinese website!