Using Goroutines for Data Processing
In Go, goroutines are lightweight threads that enables concurrent execution of tasks. When working with goroutines, it's important to properly gather results after processing to avoid deadlocks.
Problem Statement
Consider the following code snippet:
sampleChan := make(chan sample) var wg sync.WaitGroup // Read from contents list for i, line := range contents { wg.Add(1) // Process each item with a goroutine and send output to sampleChan go newSample(line, *replicatePtr, *timePtr, sampleChan, &wg) } wg.Wait() // Read from sampleChan and put into a slice var sampleList []sample for s := range sampleChan { sampleList = append(sampleList, s) } close(sampleChan)
This code tries to process items in a list using goroutines and gather the results into a slice. However, it encounters a deadlock error because the channel is closed before the results are collected.
Solution
To resolve this issue, we can asynchronously close the channel after all the workers have finished processing. Here's the corrected code:
for i, line := range contents { wg.Add(1) // Process each item with a goroutine and send output to sampleChan go newSample(line, *replicatePtr, *timePtr, sampleChan, &wg) } go func() { wg.Wait() close(sampleChan) }() for s := range sampleChan { .. }
This code starts goroutines that process items and send results to sampleChan. Concurrently, it also starts another goroutine that waits for all workers to finish and then closes the channel. This ensures that all results are collected before the channel is closed.
Alternative Solution
For better code readability and testability, it's recommended to use a synchronous newSample function and handle the concurrency in the main goroutine.
for i, line := range contents { wg.Add(1) go func(line string) { defer wg.Done() sampleChan <- newSample(line, *replicatePtr, *timePtr) }(line) }
This approach keeps concurrency primitives localized, simplifying code maintenance and reducing the risk of errors.
The above is the detailed content of How to Avoid Deadlocks When Gathering Results from Goroutines?. For more information, please follow other related articles on the PHP Chinese website!