Table of Contents
- Introduction
- Prerequisites
- Installation and Setup
- Using sync.WaitGroup for Goroutine Synchronization
- Example: Parallel Image Processing
-
Introduction
In Go, goroutines allow us to execute concurrent operations efficiently. However, sometimes we need to ensure that all goroutines have completed before proceeding with the next steps of our program. That’s where the sync.WaitGroup
comes in. It provides a simple mechanism to synchronize goroutines and wait for them to finish.
In this tutorial, we will learn how to use the sync.WaitGroup
in Go to synchronize goroutines and wait for their completion. By the end of this tutorial, you will be able to leverage this powerful feature to handle concurrent operations effectively.
Prerequisites
To follow along with this tutorial, you should have a basic understanding of Go programming language syntax and fundamentals. You should also have Go installed on your machine.
Installation and Setup
Before we begin, let’s ensure that Go is installed and set up properly on your machine. You can check if Go is installed by running the following command in your terminal:
go version
If Go is not installed, you can download and install it from the official Go website: https://golang.org/dl/
Using sync.WaitGroup for Goroutine Synchronization
The sync
package in Go provides a WaitGroup
type that allows us to wait for a collection of goroutines to finish executing. It provides three key methods: Add()
, Done()
, and Wait()
.
The Add()
method is used to add the number of goroutines we want to wait for. We typically call Add()
before spawning the goroutines.
The Done()
method is called by each goroutine when it completes its execution. It decrements the internal counter of the WaitGroup
.
The Wait()
method blocks until the internal counter becomes zero. It effectively waits for all the goroutines to call Done()
.
Let’s now dive into an example to see how to use the sync.WaitGroup
to synchronize goroutines.
Example: Parallel Image Processing
Suppose we have a list of images that we want to process concurrently. We can start a goroutine for each image, process them independently, and then wait for all the goroutines to finish before proceeding to the next step.
Here’s an example of parallel image processing using the sync.WaitGroup
:
package main
import (
"fmt"
"sync"
"time"
)
func processImage(image string, wg *sync.WaitGroup) {
defer wg.Done()
// Simulate processing time
time.Sleep(1 * time.Second)
fmt.Println("Processed image:", image)
}
func main() {
images := []string{"image1.jpg", "image2.jpg", "image3.jpg"}
var wg sync.WaitGroup
wg.Add(len(images))
for _, image := range images {
go processImage(image, &wg)
}
wg.Wait()
fmt.Println("All images processed.")
}
In this example, we define a processImage
function that takes an image filename and a pointer to a sync.WaitGroup
. Inside the function, we simulate the image processing by sleeping for 1 second. Then, we call wg.Done()
to indicate that this goroutine has finished processing.
In the main
function, we create a sync.WaitGroup
and add the number of images to it using wg.Add(len(images))
. This sets the internal counter of the WaitGroup
to the number of goroutines we expect to wait for.
Next, we iterate over the images
slice and spawn a goroutine for each image, passing the image filename and a pointer to the WaitGroup
to the processImage
function.
After spawning all the goroutines, we call wg.Wait()
to block the execution until the internal counter becomes zero, i.e., until all the goroutines have called wg.Done()
.
Finally, we print a message indicating that all the images have been processed.
Let’s run this program and see the output:
Processed image: image1.jpg
Processed image: image3.jpg
Processed image: image2.jpg
All images processed.
As you can see, the images are processed concurrently, and the final message is only printed after all goroutines have completed.
Conclusion
In this tutorial, we learned how to use the sync.WaitGroup
in Go to synchronize goroutines and wait for their completion. We explored the methods provided by the WaitGroup
type: Add()
, Done()
, and Wait()
. We then implemented a parallel image processing example to demonstrate the usage of sync.WaitGroup
.
By leveraging the sync.WaitGroup
, we can ensure our goroutines are synchronized and wait for them to complete before proceeding with the rest of our program. This allows for efficient and concurrent execution of tasks in Go.
Now that you understand the basics of sync.WaitGroup
, you can apply this knowledge to scenarios where synchronization between goroutines is required.
Happy coding!