Go Concurrency: Goroutines and Channels Explained
Go's concurrency model uses goroutines (lightweight threads) and channels (typed message pipes) to build efficient concurrent programs.
## Goroutines
```go
func main() {
go sayHello() // Launch goroutine
time.Sleep(1 * time.Second)
}
func sayHello() {
fmt.Println("Hello from goroutine")
}
```
## Channels
```go
ch := make(chan string)
// Send
go func() { ch <- "hello" }()
// Receive
msg := <-ch
fmt.Println(msg)
```
## Buffered Channels
```go
ch := make(chan int, 3)
ch <- 1
ch <- 2
ch <- 3
```
## Select Statement
```go
select {
case msg := <-ch1:
fmt.Println("ch1:", msg)
case msg := <-ch2:
fmt.Println("ch2:", msg)
case <-time.After(5 * time.Second):
fmt.Println("timeout")
}
```
## Worker Pool
```go
jobs := make(chan int, 100)
results := make(chan int, 100)
for w := 1; w <= 3; w++ {
go worker(w, jobs, results)
}
for j := 1; j <= 9; j++ {
jobs <- j
}
close(jobs)
```
## WaitGroup
```go
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
fmt.Printf("Worker %d\n", id)
}(i)
}
wg.Wait()
```
## Mutex
```go
var mu sync.Mutex
var count int
func increment() {
mu.Lock()
defer mu.Unlock()
count++
}
```
## Conclusion
Go makes concurrency simple and safe. Use goroutines for parallelism, channels for communication, and sync primitives when sharing memory.
