Вы можете проверить исходный код Go и легко узнать: это происходит в этой функции , которая вызывается в различных местах, где программа может перейти в состояние тупика.
Соответствующая часть заключается в том, что среда выполнения получает количество открытых потоков ОС и проверяет, сколько из них фактически выполняет код. Есть еще несколько проверок, но это в основном все. Всякий раз, когда вы запускаете операцию блокировки - например, блокировку мьютекса, когда он уже был заблокирован в другом месте, или получение из пустого канала - планировщик будет пытаться заставить поток выполнять работу другой процедуры. Если ни один не может быть найден, он переходит в состояние ожидания.
Обычно планировщик всегда пытается найти код, ожидающий запуска. Если ничего не найдено, то это тупиковая ситуация.
Это, конечно, исключает случаи, когда запускаются программы time.Sleep
, которые хотя и "простаивают", но есть поток, активно проверяющий, когда они готовы к запуску. Другими словами, они не зависят от других частей программы, чтобы снова стать «работоспособными» (например, в случае мьютексов).