Home >Backend Development >Golang >How to Resolve Go Deadlocks Caused by Asynchronous Operations and Empty Channels?
Deadlock in Go: "all go routines are asleep"
When running the provided code, a deadlock occurs due to its asynchronous execution model using goroutines. The issue arises when the UnloadTrucks function is called before any trucks have been sent to the channel. This leads to the channel remaining empty, causing the sender goroutines to block at the line ch <- tr. Since the sender goroutines are waiting to send trucks, they cannot close the channel, and the UnloadTrucks function, which is waiting to receive trucks, is stuck indefinitely.
Solution: Using WaitGroup to Close Channel
To resolve the deadlock, we can close the channel ch after all goroutines have finished sending trucks. This can be achieved by introducing a WaitGroup, a synchronization primitive that tracks the number of pending goroutines:
go func() { wg.Wait() close(ch) }()
This goroutine waits until all other goroutines have completed their tasks (signaled by the Wait() call) before closing the channel. By doing so, the UnloadTrucks function is able to exit gracefully when all trucks have been sent.
Revised Code:
package main import ( "fmt" "sync" "time" ) type Item struct { name string } type Truck struct { Cargo []Item name string } func UnloadTrucks(c chan Truck) { for t := range c { fmt.Printf("%s has %d items in cargo: %s\n", t.name, len(t.Cargo), t.Cargo[0].name) } } func main() { trucks := make([]Truck, 2) ch := make(chan Truck) var wg sync.WaitGroup for i, _ := range trucks { trucks[i].name = fmt.Sprintf("Truck %d", i+1) fmt.Printf("Building %s\n", trucks[i].name) } for t := range trucks { go func(tr Truck) { itm := Item{} itm.name = "Groceries" fmt.Printf("Loading %s\n", tr.name) tr.Cargo = append(tr.Cargo, itm) ch <- tr wg.Done() }(trucks[t]) wg.Add(1) } time.Sleep(50 * time.Millisecond) fmt.Println("Unloading Trucks") UnloadTrucks(ch) fmt.Println("Done") }
With this modified code, the deadlock is eliminated because the UnloadTrucks function is guaranteed to receive all trucks before the channel is closed. This ensures that all goroutines complete their tasks properly and the program runs without any unexpected interruptions.
The above is the detailed content of How to Resolve Go Deadlocks Caused by Asynchronous Operations and Empty Channels?. For more information, please follow other related articles on the PHP Chinese website!