Найти в Дзене

#21 Отличие горутин от потоков

Горутина — блок кода, который работает асинхронно. Объявляется через оператор go перед функцией. Главной горутиной является вызов функции main. Если завершается выполнение этой функции, то завершается и выполнение всей программы. Размер Системный поток имеет блок памяти фиксированного размера (стек), который зависит от операционной системы. Например, для Windows размер стека обычно 1 МБ. В Linux размер стека для потоков, как правило, составляет от 2 до 10 МБ, в зависимости от дистрибутива и настроек ядра. Размер стека горутины начинается с небольшого значения и может расширяться по мере необходимости. Минимальный размер стэка составляет 2 КБ. Максимальный зависит от архитектуры и равен 1 ГБ для 64-разрядной архитектуры, 250 МБ для 32-разрядной. Если размер стэка превышен (к примеру запустили бесконечную рекурсию), то приложение упадет с fatal error. Количество горутин ограничено только оперативной памятью системы. Планирование Потоки планируются в ядре. Горутины управляются рантаймом
Оглавление

Горутина — блок кода, который работает асинхронно. Объявляется через оператор go перед функцией. Главной горутиной является вызов функции main. Если завершается выполнение этой функции, то завершается и выполнение всей программы.

Размер

Системный поток имеет блок памяти фиксированного размера (стек), который зависит от операционной системы. Например, для Windows размер стека обычно 1 МБ. В Linux размер стека для потоков, как правило, составляет от 2 до 10 МБ, в зависимости от дистрибутива и настроек ядра.

Размер стека горутины начинается с небольшого значения и может расширяться по мере необходимости. Минимальный размер стэка составляет 2 КБ. Максимальный зависит от архитектуры и равен 1 ГБ для 64-разрядной архитектуры, 250 МБ для 32-разрядной. Если размер стэка превышен (к примеру запустили бесконечную рекурсию), то приложение упадет с fatal error. Количество горутин ограничено только оперативной памятью системы.

Планирование

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

Горутины управляются рантаймом Go. Планировщик мультиплексирует /раскидывает горутины (m) по (n) потокам. Основной плюс — это отсуствие оверхеда на переключение контекста.

Как горутины делят между собой процессорное время

Существует 2 типа многозадачности:

кооперативная — передачей управления процессы занимаются самостоятельно;

вытесняющая — планировщик дает отработать процессам равное время, после чего переключает контекст.

С версии Go 1.14 планировщик с кооперативного стал асинхронно вытесняющим.

Переключение контекста

Ожидание I/O операций: Когда горутина выполняет операцию ввода-вывода, например, чтение из файла или ожидание ответа сетевого запроса, она блокируется до завершения этой операции. В этот момент планировщик Go может переключиться на другую горутину, которая готова к выполнению.

Системные вызовы (sys call): Cистемные вызовы, которые могут занять значительное время, также приводят к переключению контекста.

Операции синхронизации: Горутины могут быть приостановлены при попытке доступа к ресурсу, который заблокирован другой горутиной (например, при использовании мьютексов или ожидании в каналах). Пока горутина ожидает разблокировки ресурса, планировщик может переключиться на выполнение других горутин.

runtime.Gosched(): Можно явно вызвать функцию runtime.Gosched() в коде, чтобы уступить время процессора другим горутинам.

Долгие вычисления: Если горутина выполняет длительные вычислительные операции без каких-либо прерываний (~10мс), планировщик переключит контекст, чтобы предотвратить зависание других горутин.

Вызов функций, поддерживающих переключение контекста: Некоторые функции, такие как time.Sleep() или блокировка на канале, также могут привести к переключению контекста.

GOMAXPROCS

Параметр, который определяет количество потоков ОС, которые могут одновременно выполнять горутины. Другими словами, GOMAXPROCS определяет максимальное количество ядер процессора, которые Go-программа может использовать одновременно. Если параметр установлен в значение большее, чем количество ядер, дополнительные потоки не улучшат производительность.

GOMAXPROCS влияет на параллелизм, а не на конкурентность. Горутины всегда могут работать конкурентно (то есть переключаться между собой), но количество горутин, которые могут выполняться параллельно, ограничено значением GOMAXPROCS.

Способы остановки всех горутин в приложении

завершение main функции и main горутины;

прослушивание всеми горутинами канала, при закрытии которого отправляется значение по умолчанию всем слушателям, при получении сигнала все горутины делают return;

завязать все горутины на переданный в них context.