sync.WaitGroup is a practical synchronization mechanism provided by the sync package in the Golang standard library, primarily used for waiting for a group of goroutines to complete their execution.
The core purpose of sync.WaitGroup is to wait for a group of goroutines to complete their execution. It ensures that the main goroutine does not exit until all other goroutines have completed. This is highly beneficial for managing concurrent tasks, especially when you cannot determine the exact number of goroutines to start or when there are complex dependencies between them.
Specifically, sync.WaitGroup provides the following methods:
Add(delta int): Used to specify the number of goroutines to wait for.deltacan be positive or negative, indicating an increase or decrease in the count.Done(): Call this method to indicate that a goroutine has completed, which internally callsAdd(-1).Wait(): Calling this method blocks the current goroutine until all goroutines have completed, i.e., the count reaches zero.
Example Usage
Consider a concrete example where we need to concurrently handle multiple HTTP requests; we can use sync.WaitGroup to wait for all requests to complete:
gopackage main import ( "net/http" "sync" "fmt" ) func main() { var wg sync.WaitGroup urls := []string{ "http://www.google.com", "http://www.facebook.com", "http://www.baidu.com", } for _, url := range urls { // Increment the counter by 1 for each goroutine launched wg.Add(1) go func(url string) { defer wg.Done() // Ensure the counter is decremented after the goroutine completes _, err := http.Get(url) if err != nil { fmt.Println(err) return } fmt.Println("Fetched", url) }(url) } // Wait for all requests to complete wg.Wait() fmt.Println("All requests are done!") }
In this example, we concurrently handle multiple HTTP requests, each executed in a separate goroutine. We use wg.Add(1) to signal the start of a new task, and defer wg.Done() at the end of each goroutine to signal completion. The wg.Wait() in the main goroutine blocks until all child goroutines have completed, i.e., all HTTP requests are processed, after which the program proceeds to print "All requests are done!".
By leveraging sync.WaitGroup, we can effectively manage and synchronize complex concurrent operations, ensuring the program executes correctly and resources are utilized efficiently.