Ich habe gerade das Golang-GMP-Modell gelernt und verstehe jetzt, wie Goroutinen, Betriebssystem-Threads und Golang-Kontext/Prozessoren miteinander zusammenarbeiten. Aber ich verstehe immer noch nicht, wann M und P generiert werden?
Zum Beispiel habe ich einen Testcode, um einige Vorgänge in der Datenbank auszuführen, und es gibt zwei Testfälle (zwei Chargen von Goroutinen):
func Test_GMP(t *testing.T) { for _ = range []struct { name string }{ {"first batch"}, {"second batch"}, } { goroutineSize := 50 done := make(chan error, goroutineSize) for i := 0; i < goroutineSize; i++ { go func() { // do some databases operations... // each goroutine should be blocked here for some time... // propogate the result done <- nil }() } for i := 0; i < goroutineSize; i++ { select { case err := <-done: assert.NoError(t, err) case <-time.After(10 * time.Second): t.Fatal("timeout waiting for txFunc goroutine") } } close(done) } }
Nach meinem Verständnis wird M bei Bedarf erstellt. Im ersten Batch von Goroutinen werden 8 (Anzahl der virtuellen Kerne auf meiner Maschine) Betriebssystem-Threads erstellt, im zweiten Batch werden nur diese 8 Betriebssystem-Threads wiederverwendet, ohne neue Threads zu erstellen. Ist das richtig?
Wir wären Ihnen dankbar, wenn Sie weitere Materialien oder Blogs zu diesem Thema bereitstellen könnten.
M kann nur wiederverwendet werden, wenn Ihr Prozess nicht blockiert ist oder keine Systemaufrufe hat. In Ihrem Fall haben Sie Blockierungsaufgaben in go func()
. Daher ist die Anzahl der M nicht auf 8 (die Anzahl der virtuellen Kerne auf meiner Maschine) beschränkt. Der erste Stapel wird P blockieren und entfernen und auf den Abschluss des Blockierungsvorgangs warten, während ein neues M erstellt wird, das P zugeordnet ist.
Weitere Informationen finden Sie weiter unten,
Das obige ist der detaillierte Inhalt vonWann erstellt der Go-Scheduler neue M und P?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!