Расскажи про планировщик Go. Как он работает с блокирующими операциями?
Answer from AI
sobes.tech AI
Планировщик Go (runtime scheduler) управляет выполнением горутин — легковесных потоков, которые Go создает для конкурентного выполнения кода. Он использует модель M:N, где M — системные потоки (OS threads), а N — горутины.
Основные компоненты:
- G (goroutine) — объект горутины.
- M (machine) — системный поток ОС.
- P (processor) — логический процессор, который связывает G и M.
Планировщик распределяет горутины на доступные P, которые запускаются на M.
Работа с блокирующими операциями: Если горутина выполняет блокирующую операцию (например, системный вызов, чтение из сети), планировщик может:
- Отсоединить M от текущего P и запустить другой M с другим P, чтобы не блокировать выполнение других горутин.
- Запустить новую системную нить (M), если все M заблокированы, чтобы обеспечить выполнение других горутин.
Таким образом, блокирующие операции не блокируют весь планировщик, а только конкретный поток ОС, и runtime старается компенсировать это, создавая новые потоки или перераспределяя горутины.
Пример:
func main() {
go func() {
time.Sleep(time.Second) // блокирующая операция
fmt.Println("Горутина 1")
}()
go func() {
fmt.Println("Горутина 2")
}()
time.Sleep(2 * time.Second)
}
Здесь, несмотря на блокировку первой горутины, вторая выполнится без задержек благодаря планировщику.