Concurrency is when a large task is split into smaller sub-tasks and run at the same time. This post provides an outline of how Go handles concurrency.
Goroutines are an integral part of Go. They are the units of execution inside a Go program. The main function is also another goroutine. They all have very small stack sizes, which allows spawning millions of them at the same time. They are extremely lightweight. Read here more about how goroutines work.
Channels are a medium via which goroutines communicate. It is the primary medium for sending and receiving information. Channels’ send and receive operations are blocking. They can be unidirectional or bidirectional and can send any data through them. Read here more about channels.
The select statement works like a switch statement but for channels only. Its execution depends entirely on what case produces output fast. If it becomes undecidable such that multiple cases are producing output then it will choose the case randomly.
Waitgroups allow waiting for goroutines. So, when multiple goroutines are being executed it will allow it to wait for each of them to finish. It is an important idea that makes the go concurrency worth it. The sync package contains wait group struct. Here is more about how to use wait groups.
Atomics are special data types that use CPU instructions to provide synchronized access. It works as a shared variable between goroutines. It mainly is used when we need to synchronize read-write access to a variable via multiple goroutines. The
sync/atomic package in Go contains atomics.
Mutexes are mutual exclusion. By using mutexes goroutines can have concurrent access to any data. It is a very common concept in threading that appears in many different programming languages. Go has the sync package which contains the mutex struct that is ready to use.