Горутина — это структура runtime.g с собственным стеком, program counter и состоянием. Go runtime использует модель GMP:
- G (Goroutine) — задача со стеком (~2-8 КБ, растёт динамически до 1 ГБ)
- M (Machine) — OS-поток, выполняет код
- P (Processor) — логический процессор, связывает G и M. Количество = GOMAXPROCS
P0 P1
[runq] [runq]
G1 G2 G3 G4 G5
| |
M0 M1 ← OS-потоки
Жизненный цикл:
1. go f() → создаётся G, помещается в локальную очередь P
2. P берёт G из своей очереди и выполняет на M
3. Если очередь пуста — work stealing: крадёт G у другого P
4. При блокирующем syscall — M отцепляется от P, P берёт другой M (или создаёт новый)
Стек горутины:
- Начальный размер ~2-8 КБ
- Растёт сегментно (stackcopy): при переполнении аллоцируется стек x2, содержимое копируется
- Поэтому указатели на стек могут меняться — Go runtime это учитывает