Горутины, каналы, context, sync, гонки.
Лекции
Data race и memory model
Data race — две горутины трогают одну переменную, среди доступов есть запись, и нет договорённости «кто раньше». Это баг, а не «на моей машине работает».
WaitGroup, Once, атомики
WaitGroup ждёт набор горутин. Once гарантирует один вызов функции. atomic закрывает простые счётчики. Составное условие из нескольких полей атомиком не защитить.
Mutex, RWMutex и каналы как синхронизация
Mutex защищает общую память. Канал передаёт владение значением между горутинами. RWMutex выгоден, когда чтений много, а запись редкая.
Context: cancel, deadline, values
Context несёт отмену и дедлайн вниз по вызовам. Values годятся для редких полей запроса вроде trace id, а не для логгера, конфига и внедрения зависимостей.
Select, таймаут и default
select ждёт, пока будет готов хотя бы один case, и среди готовых выбирает случайный. default — попытка без ожидания. Таймаут делают через timer или context, не через бесконечный sleep.
Каналы: буфер, close, владение
Канал передаёт значения и синхронизирует горутины. Закрывает тот, кто пишет. Send в закрытый канал — panic. Receive из закрытого — нуль типа и ok=false.
Горутины и планировщик GMP
Горутина — дешёвая единица работы со своим стеком, не поток ОС. Планировщик связывает G (горутина), M (поток) и P (очередь исполнения).