Practical Examples
Real-World WaitGroup Scenarios
1. Parallel Web Scraping
package main
import (
"fmt"
"io/ioutil"
"net/http"
"sync"
)
func fetchURL(url string, wg *sync.WaitGroup, results chan string) {
defer wg.Done()
resp, err := http.Get(url)
if err != nil {
results <- fmt.Sprintf("Error fetching %s: %v", url, err)
return
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
results <- fmt.Sprintf("%s: %d bytes", url, len(body))
}
func main() {
urls := []string{
"https://www.example.com",
"https://www.github.com",
"https://www.golang.org",
}
var wg sync.WaitGroup
results := make(chan string, len(urls))
for _, url := range urls {
wg.Add(1)
go fetchURL(url, &wg, results)
}
// Wait for all goroutines to complete
go func() {
wg.Wait()
close(results)
}()
// Collect and print results
for result := range results {
fmt.Println(result)
}
}
2. Concurrent File Processing
func processFiles(files []string) {
var wg sync.WaitGroup
var mu sync.Mutex
processedFiles := []string{}
for _, file := range files {
wg.Add(1)
go func(filepath string) {
defer wg.Done()
// Simulate file processing
content, err := ioutil.ReadFile(filepath)
if err != nil {
fmt.Printf("Error processing %s: %v\n", filepath, err)
return
}
mu.Lock()
processedFiles = append(processedFiles, filepath)
mu.Unlock()
}(file)
}
wg.Wait()
fmt.Printf("Processed %d files\n", len(processedFiles))
}
Synchronization Patterns
graph TD
A[WaitGroup Usage] --> B[Parallel Processing]
A --> C[Resource Coordination]
A --> D[Controlled Concurrency]
Practical Synchronization Scenarios
Scenario |
WaitGroup Benefit |
Complexity |
Web Scraping |
Parallel URL Fetching |
Medium |
File Processing |
Concurrent File Handling |
Medium |
API Requests |
Simultaneous API Calls |
Low |
Advanced Techniques
Timeout Management
func processWithTimeout(tasks []string, timeout time.Duration) {
var wg sync.WaitGroup
done := make(chan bool)
go func() {
wg.Wait()
close(done)
}()
select {
case <-done:
fmt.Println("All tasks completed")
case <-time.After(timeout):
fmt.Println("Processing timed out")
}
}
Key Takeaways
- WaitGroup enables efficient concurrent processing
- Combine with channels for advanced synchronization
- Use mutexes to protect shared resources
- Implement timeouts for long-running tasks
Note: LabEx encourages exploring these practical WaitGroup applications to master concurrent programming in Go.