Chapter 08: Concurrency
"Concurrency is not Parallelism." - Rob Pike
Up until now, your code did one thing at a time. It was a single worker. But real shops start doing many things at once. One clerk checks credentials, another fetches the product, a third calculates shipping.
In Go, we don't have "Threads" (which are heavy, like 2MB each). We have Goroutines (which are light, like 2KB each). You can launch millions of them.
1 The Worker (Goroutine)
To start a task in the background, just put go in front of it.
func main() {
go sendEmail("Welcome!") // Leaves immediately!
fmt.Println("Done")
}This spawns a new "Elf" to do the work. The main function doesn't wait for him. It finishes and exits. Warning: If main dies, all Elves die instantly, even if they aren't finished.
2 The Conveyor Belt (Channels)
If Elves work silently, how do they talk? They use Channels. Think of a Channel as a pipe. One Elf puts data in one end, another takes it out the other.
ch := make(chan string)
go func() {
ch <- "Job Done!" // Send
}()
msg := <-ch // Receive (Waits until data arrives)2.1 The Visual Signal (The Conveyor Belt)
Concept: Safe communication between concurrent Goroutines. Signal: A Factory Conveyor Belt. Workers (Goroutines) put items on, other workers take them off. No one fights over the item; the belt manages the handoff.
3 The Worker Pool (The Shop Floor)
Imagine 1,000 customers click "Buy" at once. If you start 1,000 background jobs, you might crash the server. Instead, we use a Buffered Channel as a waiting line.
- Handler: Puts order in the queue and returns "Success" instantly (User is happy).
- Queue: Holds orders until the Worker is ready (Buffer).
- Worker: Processes orders one by one (or in a pool).
4 The Toilet Lock (Mutex)
Sometimes, two workers need to use the same resource (like a map or a counter). If they touch it at the same time, data gets corrupted (Race Condition). We need a lock. In Go, it's sync.Mutex.
Think of it like a Toilet Door.
- Lock(): You enter and lock the door. Everyone else waits outside.
- Unlock(): You leave. The next person can enter.
mu.Lock()
count++ // Safe zone
mu.Unlock()🎓 Knowledge Check: What is a Race Condition?
Answer: A bug where two threads/goroutines try to write to the same memory at the same time. The result is unpredictable garbage. Fixing it requires synchronization (Mutex or Channels).
