← Назад ко всем вопросам

Как работает Scheduler

1️⃣ Как кратко ответить

Scheduler в Go управляет планированием выполнения горутин, распределяя их по системным потокам. Он использует модель M:N, где M — количество горутин, а N — количество системных потоков. Это позволяет эффективно использовать ресурсы процессора, обеспечивая конкурентное выполнение кода.

2️⃣ Подробное объяснение темы

Scheduler в Go — это компонент, который отвечает за управление выполнением горутин. Горутины — это легковесные потоки, которые позволяют выполнять функции конкурентно. Scheduler в Go реализует модель M:N, где M — количество горутин, а N — количество системных потоков (OS threads). Это позволяет эффективно использовать ресурсы процессора и обеспечивает высокую производительность.

Основные компоненты Scheduler

  1. Goroutine (G): Легковесная задача, которая выполняется конкурентно. Каждая горутина имеет свой стек и состояние выполнения.

  2. Machine (M): Представляет собой системный поток, который выполняет горутины. M управляет выполнением G и взаимодействует с операционной системой.

  3. Processor (P): Логический процессор, который распределяет горутины между M. P содержит очередь горутин, готовых к выполнению.

Как работает Scheduler

  • Инициализация: При запуске программы Go создается несколько P (по умолчанию равное количеству логических процессоров на машине). Каждому P назначается M, который будет выполнять горутины.

  • Планирование: Горутины добавляются в очередь P. Когда M становится доступным, он берет горутину из очереди P и начинает ее выполнение.

  • Вытеснение: Если горутина блокируется (например, ожидает ввода-вывода), M может переключиться на другую горутину из очереди P, чтобы не простаивать.

  • Балансировка нагрузки: Если одна из очередей P становится слишком длинной, Scheduler может переместить горутины между P, чтобы сбалансировать нагрузку.

Пример кода

package main
​
import (
	"fmt"
	"time"
)
​
func printNumbers() {
	for i := 1; i <= 5; i++ {
		fmt.Println(i)
		time.Sleep(100 * time.Millisecond) // Пауза для имитации работы
	}
}
​
func printLetters() {
	for i := 'a'; i <= 'e'; i++ {
		fmt.Printf("%c\n", i)
		time.Sleep(150 * time.Millisecond) // Пауза для имитации работы
	}
}
​
func main() {
	go printNumbers() // Запуск горутины для печати чисел
	go printLetters() // Запуск горутины для печати букв
​
	time.Sleep(1 * time.Second) // Ожидание завершения горутин
}
  • printNumbers и printLetters — функции, которые будут выполняться в горутинах.
  • go printNumbers() и go printLetters() — запуск горутин для выполнения функций.
  • time.Sleep(1 * time.Second) — основная горутина ждет завершения других горутин.

Зачем нужен Scheduler

Scheduler позволяет эффективно использовать многопоточность, обеспечивая конкурентное выполнение кода без необходимости вручную управлять потоками. Это упрощает разработку многопоточных приложений и позволяет Go-программам масштабироваться на многопроцессорных системах.

Тема: Конкурентность
Стадия: Tech

🔒 Подпишись на бусти автора и стань Алигатором, чтобы получить полный доступ к функционалу сайта и отслеживать свой прогресс!

Твои заметки