Middle+
გთხოვთ, ისაუბროთ კონკურენციის მართვის ნიმუშზე (GMP) პროგრამულ ენაში Go.
sobes.tech AI
პასუხი AI-სგან
GMP - ეს არის გორუტინების შესრულების დაგეგმვის მოდელი Go-ში, სადაც:
- G (Goroutine): მსუბუქი წონით ნაკლები ნაკადი, აბსტრაქცია სისტემური ნაკადების ზევით.
- M (Machine): ოპერაციული სისტემის ნაკადი. შეუძლია ერთდროულად რამდენიმე გორუტინის შესრულება.
- P (Processor): ლოგიკური პროცესორი, რომელიც წარმოადგენს კონტექსტს გორუტინების შესრულებისთვის. თითოეულ P-ს მინიჭებულია M, და P შეიცავს ადგილობრივ რიგს runnable გორუტინებისთვის. P-ს რაოდენობა ჩვეულებრივ შეესაბამება
$GOMAXPROCS-ს (საშუალოდ CPU-ების რაოდენობა).
როგორ მუშაობს:
- გრაფიკი (Go-ის runtime-ის ნაწილი) სვამს ახალი გორუტინებს გლობალურ ან ადგილობრივ P-ის რიგში.
- დაკავშირებული M იღებს გორუტინას P-ის რიგიდან და ასრულებს მას.
- როდესაც გორუტინა ბლოკდება (მაგალითად, I/O-ს მოლოდინში ან მუტექსზე):
- M გამორთულია მიმდინარე P-დან.
- გრაფიკი ცდილობს სხვა M-ის მოძებნას, რათა ის დაკავდეს ამ P-ით, ან შექმნას ახალი.
- ბლოკირებული გორუტინა განთავსებულია სპეციალურ რიგში.
- როდესაც ბლოკირება მოიხსნება, გორუტინა კვლავ ხდება runnable და დაბრუნდება P-ის რიგში.
- როდესაც გორუტინა ამოწურავს თავის დროის კვანტს ან აშკარად გადმოეცემა მართვა (ძირითადად იშვიათია), გრაფიკი შეიძლება შეცვალოს 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) // გორუტინების დასრულების მოლოდინი
}