Creating an OS Thread or switching from one to another can be costly for your programs in terms of memory and performance. Go aims to get advantages as much as possible from the cores. It has been designed with concurrency in mind from the beginning.
M, P, G orchestration
To solve this problem, Go has its own scheduler to distribute goroutines over the threads. This scheduler defines three main concepts, as explained in the code itself:
The main concepts are: G - goroutine. M - worker thread, or machine. P - processor, a resource that is required to execute Go code. M must have an associated P to execute Go code[...].
Here is a diagram of this
Each goroutine (
G) runs on an OS thread (
M) that is assigned to a logical CPU (
P). Let’s take a simple example to see how Go manages them…