Презентация

Многопоточность в Go: горутины, каналы и частые ошибки

Материал про конкурентность и параллельность, устройство горутин, каналы, мьютексы и типичные проблемы в многопоточном коде.

О чем этот материал

Concurrency, goroutines, channels, mutexes и базовые правила безопасной работы.

Это адаптированная версия учебной презентации: слайды разобраны в формате обычной статьи, чтобы материал было легче читать с телефона и возвращаться к нужным блокам позже.

Что внутри

Ниже краткий план материала. По нему удобно понять, в каком порядке разбирать тему.

  1. Поговорим об основных понятиях многопоточности
  2. Поговорим о том, как это реализовано в Go
  3. Горутины
  4. Каналы
  5. Мютексы
  6. Поговорим о частых ошибках при работе с горутинами
  7. Рассмотрим best practices при работе с горутинами
  8. Разберем вопросы

Многозадачность

(ядро) переключается между процессами поочередно, предоставляя каждому процессу какой-то квант времени на выполнение.

одновременно, каждая исполняется отдельным ядром процессора

Какой тип многозадачности используется в Go?

Какой тип многозадачности используется в Go?

  • Конкурентность запущенные программы конкурируют за ресурсы. Процессор
  • Параллельность запущенные программы в реальном времени выполняются
  • Полностью изолированы
  • Могут шарить память в
  • Больше ресурсов на
  • Дешевле по ресурсам
  • Как правило отдельные
  • Как правило внутри одной

Goroutines

Горутины

выполнения) Go

тоже заканчивают

  • легковесные потоки, которые управляются рантаймом (runtime, средой
  • как только функция выполнится - горутина умирает запуск main() - это тоже горутина как только родительская горутина заканчивает работу - все “дочерние”

Channels

Каналы

Каналы

  • средство коммуникации между горутинами представляет собой очередь (FIFO - First In - First Out) еще можно представить как трубу, только с “дверцей” на выходе
  • бывают буферизированные и нет если нет, то “труба” превращается в кольцо
  • запись в заполненный канал - блокирующая операция чтение из пустого канала - блокирующая операция select {case: … case: … } чтобы не блокироваться

Многопоточность

Работа с глобальными переменными map[type]type{} - не является безопасной при конкурентном доступе

  • Читать из разных горутин - можно
  • Писать из разных горутин - нельзя (panic)

sync.Mutex

Используется для блокировки объектов во время конкурентной работы

Mutex

sync.Map

Частые ошибки

Горутинам нужно время на выполнение

Горутинам нужно время на выполнение

Горутины выполняются в порядке как попало

Горутины выполняются в порядке как попало

Бест практисы

Worker pool

Когда не хотим (а мы не хотим) бесконтрольно плодить горутины

Context cancellation

Когда пора заканчивать и домой

Бест практисы errgroup

Бест практисы

Бонус