Welcome to our deep dive into Go Concurrency! This comprehensive lesson is designed to equip you with the knowledge you need to excel in Go interviews and real-world projects. Let's get started! š
Concurrency is the ability of Go programs to run multiple tasks or routines concurrently. It's a powerful feature that allows efficient execution of CPU-bound tasks and responsive I/O operations.
package main
import "fmt"
func main() {
go func() {
fmt.Println("Hello from Go Routine 1")
}()
go func() {
fmt.Println("Hello from Go Routine 2")
}()
fmt.Println("Hello from Main")
}ā
In the above example, we have two go routines running concurrently, and the main function prints a greeting as well.
Goroutines are the basic units of concurrency in Go. They're lightweight threads managed by the Go runtime. Channels allow communication between Goroutines.
package main
import "fmt"
func worker(id int, jobs <-chan int, results chan<- int) {
for j := range jobs {
fmt.Println("Worker", id, "processing job", j)
results <- j * 2 // send the result back to main
}
}
func main() {
jobs := make(chan int, 100)
results := make(chan int, 100)
// sending work to workers
for w := 1; w <= 3; w++ {
go worker(w, jobs, results)
}
// filling the jobs channel with work
for j := 1; j <= 9; j++ {
jobs <- j
}
close(jobs) // inform the workers that no more work will be sent
// receiving results and printing them
for a := 1; a <= 9; a++ {
<-results
}
}ā In the above example, we have created a worker function that accepts jobs from a channel, processes them, and sends the results to another channel. The main function manages the workers, sends jobs to them, and collects the results.
Mutexes (MUTual EXclusion) are used to protect shared variables from concurrent access, ensuring data consistency and preventing race conditions.
package main
import (
"fmt"
"sync"
)
var counter int
var lock sync.Mutex
func incrementCounter(wg *sync.WaitGroup) {
defer wg.Done()
lock.Lock()
defer lock.Unlock()
counter++
fmt.Println("Incremented counter:", counter)
}
func main() {
var wg sync.WaitGroup
// increasing the counter concurrently 10 times
for i := 1; i <= 10; i++ {
wg.Add(1)
go incrementCounter(&wg)
}
wg.Wait()
}ā In the above example, we use a Mutex to protect the shared counter variable and ensure that it's incremented safely by multiple Goroutines.
What is Concurrency in Go?
We hope you enjoyed learning about Go Concurrency! Keep practicing and happy coding! š