Что происходит, если GOMAXPROCS равен одному и задача блокирующая
Что проверяют
Понимаете ли вы, что GOMAXPROCS ограничивает не число потоков, а число горутин, одновременно исполняющих код Go. И отличаете ли блокировку горутины от блокировки потока: ответ на вопрос целиком зависит от того, какая именно блокировка имеется в виду.
Как отвечать
Начните с модели: планировщик связывает горутины с логическими процессорами, которых ровно GOMAXPROCS, а исполняют их потоки операционной системы, и потоков рантайм заводит столько, сколько понадобится.
Дальше по типам блокировки:
- канал, мьютекс, ожидание группы,
time.Sleep: горутина паркуется, поток свободен, планировщик сразу берёт следующую. Даже при значении, равном единице, программа продолжает работать; - сеть и таймеры обслуживает сетевой поллер, поэтому чтение из сокета тоже не занимает поток;
- настоящий блокирующий системный вызов, например работа с файлом или переход в cgo, поток занимает. Рантайм это замечает, отцепляет логический процессор от заснувшего потока и отдаёт другому, так что остальные горутины продолжают выполняться, а потоков станет больше, чем
GOMAXPROCS; - реально опасен лишь плотный вычислительный цикл без вызовов функций. Раньше он монополизировал процессор целиком, теперь рантайм вытесняет такую горутину по сигналу, но задержки всё равно заметны.
Полезно добавить про контейнеры: рантайм долго брал число ядер хоста и игнорировал лимит cgroup, отсюда привычка выставлять значение по лимиту явно.
Где спотыкаются
Отвечают, что при единице все горутины выстраиваются в очередь и любой блокирующий вызов останавливает программу. Так ведут себя планировщики без поддержки со стороны рантайма, а Go именно ради этого и держит собственный слой между горутинами и потоками.
Путают конкурентность и параллелизм. Единица не отменяет конкурентности: горутины по-прежнему чередуются, исчезает только одновременное исполнение на разных ядрах.
Считают единицу заменой синхронизации. Переключение может случиться на любом вызове функции и на любой аллокации, поэтому общий доступ без мьютекса или канала остаётся гонкой, а детектор гонок при одном логическом процессоре находит заметно меньше.