Вопрос проверяет понимание модели конкурентности в Go, основанной на горутинах и планировщике, что необходимо для написания эффективных конкурентных программ.
В Go горутины — это легковесные потоки, которые управляются не операционной системой, а собственным планировщиком языка. Планировщик Go реализует модель M:N, где M горутин выполняются на N потоков ОС. Это позволяет эффективно использовать ресурсы и создавать тысячи горутин без значительных накладных расходов.
Переключение между горутинами происходит кооперативно, то есть горутина сама уступает выполнение в определенных точках:
package main
import (
"fmt"
"runtime"
"time"
)
func worker(id int) {
for i := 0; i < 3; i++ {
fmt.Printf("Worker %d: iteration %d\n", id, i)
runtime.Gosched() // явно уступаем выполнение
}
}
func main() {
go worker(1)
go worker(2)
time.Sleep(time.Second)
fmt.Println("Main done")
}В этом примере горутины переключаются при вызове runtime.Gosched(), что позволяет планировщику распределить время между ними.
Понимание работы планировщика Go важно для написания эффективных конкурентных программ, особенно при работе с большим количеством горутин и синхронизацией через каналы.