Concurrency and Parallelism in Go

Concurrency and parallelism are important features in Go that allow you to perform multiple tasks simultaneously. Here’s an overview of how they work in Go:

1. Goroutines: A goroutine is a lightweight thread of execution in Go. Goroutines in Go are created using the `go` keyword, followed by the function to execute. For example:


func sayHello() {
fmt.Println(“Hello, world!”)
}

go sayHello()

``

   This code creates a new goroutine that executes the `sayHello` function concurrently with the main program.

2. Channels: A channel is a communication mechanism in Go that allows goroutines to send and receive values. In Go, channels are declared using the `make` function, followed by the `chan` keyword and the type of the values to be transmitted. For example:

   
`
   messages := make(chan string)

   go func() {
       messages <- "Hello, world!"
   }()

   msg := <-messages
   fmt.Println(msg)
   

``

This code creates a channel of strings and sends a message over it in a new goroutine. It then receives the message in the main goroutine and prints it.

3. WaitGroups: A WaitGroup is a synchronization mechanism in Go that allows the main goroutine to wait for the completion of all the goroutines it has spawned. In Go, WaitGroups are declared using the `sync` package and its`WaitGroup` type. For example:

``
   var wg sync.WaitGroup

   for i := 0; i < 5; i++ {
       wg.Add(1)
       go func(i int) {
           defer wg.Done()
           fmt.Println("Goroutine", i)
       }(i)
   }

   wg.Wait()
   

   This code creates a `WaitGroup` and spawns five goroutines that print their index. The `Add` method of the `WaitGroup` is used to increment the counter before each goroutine is spawned, and the `Done` method is used to decrement it after each goroutine finishes. The `Wait` method blocks until the counter reaches zero, indicating that all the goroutines have finished.

4. Parallelism: Parallelism is the act of executing multiple tasks simultaneously on different processors. In Go, parallelism can be achieved by creating multiple goroutines that execute on different processors. This can be done by setting the `GOMAXPROCS` environment variable to the number of processors available. For example:

   

``
import "runtime"

func main() {
runtime.GOMAXPROCS(2)

// ...
}


This code sets the maximum number of processors to 2, allowing two goroutines to execute in parallel.

Concurrency and parallelism are powerful features in Go that allow you to create efficient and responsive programs. By using goroutines, channels, and WaitGroups to manage concurrent execution, and by setting the `GOMAXPROCS` environment variable to achieve parallelism, you can create programs that can take advantage of modern hardware and scale well with increasing workloads.