Sobes.tech
Middle

Czym jest czas działania (runtime) i jak działa planista (scheduler)?

sobes.tech AI

Odpowiedź od AI

Środowisko wykonawcze (runtime) w Go to środowisko, w którym uruchamiane są programy Go. Obejmuje:

  • Zarządzanie pamięcią: Kolektor śmieci (garbage collector) automatycznie zarządza przydziałem i zwalnianiem pamięci.
  • Planista (scheduler): Zarządza wykonywaniem gorutyn na wątkach systemu operacyjnego.
  • Wywołania systemowe: Zapewnia interfejs do interakcji z systemem operacyjnym.
  • Prymitywy synchronizacji: Kanały, muteksy i inne mechanizmy do koordynacji gorutyn.

Planista Go implementuje model M:N (wiele gorutyn na wiele wątków systemu operacyjnego). Jego główne komponenty:

  • G (Goroutine): Lekki wątek wykonawczy, zasadniczo abstrakcja nad funkcją.
  • M (Machine): Wątek systemu operacyjnego, na którym uruchamiane są programy Go.
  • P (Processor): Logiczny procesor powiązany z wątkiem OS. Przechowuje lokalną kolejkę runnable gorutyn.

Zasada działania planisty:

  1. Gorutyny (G) są tworzone i dodawane do globalnej lub lokalnej kolejki runnable.
  2. Wątki OS (M) są powiązane z logicznymi procesorami (P). Liczba P domyślnie równa się liczbie rdzeni CPU (GOMAXPROCS).
  3. P pobiera gorutynę z własnej lokalnej kolejki. Jeśli kolejka lokalna jest pusta, P próbuje "ukraść" (steal) gorutyny z kolejki innego P lub z kolejki globalnej.
  4. M wykonuje gorutynę.
  5. Gdy gorutyna zostaje zablokowana (np. podczas odczytu z kanału bez danych lub wywołania systemowego), M odłącza się od P, a P staje się dostępny do wykonania innej gorutyny. Zablokowana gorutyna jest ustawiana w oczekiwaniu. Gdy blokada zostaje zdjęta, gorutyna ponownie staje się runnable i wraca do kolejki.
  6. Jeśli M zostaje zablokowane w wywołaniu systemowym, nie trzyma P. Może zostać utworzony nowy M lub użyty istniejący, aby P mógł kontynuować wykonywanie innych gorutyn.

To podejście pozwala efektywnie wykorzystywać zasoby procesora i łatwo skalować zadania równoległe, ukrywając złożoność zarządzania wątkami OS przed programistą.

// Przykład tworzenia gorutyny
func myFunc() {
	// Kod gorutyny
}

func main() {
	go myFunc() // Uruchomienie gorutyny
	// Główna część programu kontynuuje wykonywanie równolegle
}