In the Go language, goroutines are very lightweight threads used for concurrent task execution. Handling goroutines and obtaining their results can be implemented in various ways, with the most common methods involving the use of channels and tools from the sync package, such as WaitGroup. I will now provide a detailed explanation of these two methods, including specific examples.
1. Using Channels
Channels are used to safely pass data between different goroutines. You can use channels to obtain the execution results of goroutines.
Example:
Suppose we need to calculate the squares of multiple numbers and obtain the results.
gopackage main import ( fmt time ) func square(number int, ch chan int) { // Compute the square result := number * number // Simulate a time-consuming operation time.Sleep(time.Second) // Send the result to the channel ch <- result } func main() { ch := make(chan int) numbers := []int{2, 4, 6, 8} for _, number := range numbers { go square(number, ch) } for range numbers { fmt.Println(<-ch) } }
In this example, we define a function named square that accepts an integer and a channel, computes the square of the integer, and sends the result to the channel. In the main function, we start multiple goroutines to compute in parallel and read the results from the channel.
2. Using sync.WaitGroup
WaitGroup is used to wait for a set of goroutines to complete. You can call Add before starting a goroutine to set the counter, and call Done when each goroutine completes.
Example:
gopackage main import ( fmt "sync" time ) func square(number int, wg *sync.WaitGroup, results *[]int) { defer wg.Done() // Compute the square result := number * number // Simulate a time-consuming operation time.Sleep(time.Second) // Save the result *results = append(*results, result) } func main() { var wg sync.WaitGroup var results []int numbers := []int{2, 4, 6, 8} for _, number := range numbers { wg.Add(1) go square(number, &wg, &results) } wg.Wait() fmt.Println(results) }
In this example, we define a square function that accepts an integer, a pointer to a WaitGroup, and a pointer to a results slice. Each goroutine calls Done when it completes. By calling Wait, the main function waits for all goroutines to complete before proceeding.
Summary
Using channels and WaitGroup are two common methods for handling goroutines and obtaining results. The choice of which method depends on the specific application scenario and personal preference. Channels are particularly suitable for cases where data needs to be directly passed from goroutines, while WaitGroup is appropriate for scenarios where only waiting for a set of operations to complete is required.