Sobes.tech
Middle+

გთხოვთ, ისაუბროთ კონკურენციის მართვის ნიმუშზე (GMP) პროგრამულ ენაში Go.

sobes.tech AI

პასუხი AI-სგან

GMP - ეს არის გორუტინების შესრულების დაგეგმვის მოდელი Go-ში, სადაც:

  • G (Goroutine): მსუბუქი წონით ნაკლები ნაკადი, აბსტრაქცია სისტემური ნაკადების ზევით.
  • M (Machine): ოპერაციული სისტემის ნაკადი. შეუძლია ერთდროულად რამდენიმე გორუტინის შესრულება.
  • P (Processor): ლოგიკური პროცესორი, რომელიც წარმოადგენს კონტექსტს გორუტინების შესრულებისთვის. თითოეულ P-ს მინიჭებულია M, და P შეიცავს ადგილობრივ რიგს runnable გორუტინებისთვის. P-ს რაოდენობა ჩვეულებრივ შეესაბამება $GOMAXPROCS-ს (საშუალოდ CPU-ების რაოდენობა).

როგორ მუშაობს:

  1. გრაფიკი (Go-ის runtime-ის ნაწილი) სვამს ახალი გორუტინებს გლობალურ ან ადგილობრივ P-ის რიგში.
  2. დაკავშირებული M იღებს გორუტინას P-ის რიგიდან და ასრულებს მას.
  3. როდესაც გორუტინა ბლოკდება (მაგალითად, I/O-ს მოლოდინში ან მუტექსზე):
    • M გამორთულია მიმდინარე P-დან.
    • გრაფიკი ცდილობს სხვა M-ის მოძებნას, რათა ის დაკავდეს ამ P-ით, ან შექმნას ახალი.
    • ბლოკირებული გორუტინა განთავსებულია სპეციალურ რიგში.
    • როდესაც ბლოკირება მოიხსნება, გორუტინა კვლავ ხდება runnable და დაბრუნდება P-ის რიგში.
  4. როდესაც გორუტინა ამოწურავს თავის დროის კვანტს ან აშკარად გადმოეცემა მართვა (ძირითადად იშვიათია), გრაფიკი შეიძლება შეცვალოს M სხვა გორუტინაზე იმავე P-ში.

უპირატესობები:

  • ეფექტიანი გამოყენება სისტემური ნაკადების M-ის.
  • ნაკლები გადასვლის ხარჯები ნატიური სისტემური ნაკადების შედარებით.
  • დატვირთვის ბალანსი P-ებს შორის "work stealing" მექანიზმის საშუალებით (M შეიძლება მოიპაროს გორუტინა სხვა P-ის რიგიდან).

გორუტინის შექმნის მაგალითი:

// main.go
პაკეტი main

იმპორტი (
	"fmt"
	"time"
)

ფუნქცია worker(id int) {
	fmt.Printf("მუშაკი %d იწყება\n", id)
	time.Sleep(time.Second) // ბლოკირება/დაკავება ასლუსტრაცია
	fmt.Printf("მუშაკი %d დასრულდა\n", id)
}

ფუნქცია main() {
	for i := 1; i <= 5; i++ {
		go worker(i) // ახალი გორუტინის შექმნა
	}

	time.Sleep(time.Second * 2) // გორუტინების დასრულების მოლოდინი
}