Вышла вторая часть серии про рантайм. Первая была про то, почему поток дорогой, а горутина нет. Эта про механизмы, которых из кода не видно: стек, который переезжает по памяти целиком, вытеснение сигналом ОС и полный жизненный цикл горутины.
Шесть лет в Go существовал цикл, который невозможно было прервать. Крутится без вызовов функций, вытеснять нечем, а сборщику мусора нужна остановка мира. Вот все и вставало насмерть. Приехало это в 1.2, починили сигналом только в 1.14.
Потрогать можно прямо сейчас, современным компилятором:
GODEBUG=asyncpreemptoff=1 go run ./preempt
Программа виснет до первой строчки вывода. Без переменной отрабатывает за миллисекунды.
Что еще в статье:
- Вытеснение прилетает сигналом SIGURG, а обработчик подделывает вызов функции, которого в коде не было. Увидишь под strace ливень SIGURG, это не сломанная сеть и не атака, это планировщик работает.
- Дамп горутин разобран построчно: номер, причина ожидания, минуты зависания, created by с точным местом рождения. Самый практичный навык из всей серии, окупается на первом же инциденте.
- Детектор дедлоков в проде не сработает никогда. Он считает живые потоки, а не разбирает граф ожиданий, поэтому сотня зависших горутин при работающем HTTP-сервере для него невидима.
Третья часть через неделю... Я надеюсь :-)
https://habr.com/ru/articles/1073044/
