Heim  >  Artikel  >  Backend-Entwicklung  >  Warum verhält sich die Go-Routine so?

Warum verhält sich die Go-Routine so?

WBOY
WBOYnach vorne
2024-02-08 23:30:10715Durchsuche

为什么 go 例程会有这样的行为?

php-Redakteur Xigua wird Ihre Frage zum „Grund für das routinemäßige Verhalten“ beantworten. Die Routine (Goroutine) in der Go-Sprache ist ein leichter Parallelitätsmechanismus, der den Effekt einer gleichzeitigen Ausführung erzielen kann. In einigen Fällen kann das Verhalten von Go-Routinen jedoch zu unerwarteten Ergebnissen führen. Dies ist hauptsächlich auf den Planungsmechanismus von Go-Routinen und die Eigenschaften des Speichermodells zurückzuführen. Bevor wir das Routineverhalten der Go-Sprache tiefgreifend verstehen, müssen wir diese Funktionen und ihre Auswirkungen auf das Programmverhalten verstehen.

Frageninhalt

Ich lese ein Buch mit dem Titel „Go in action“ und bin etwas verwirrt über den Goroutine-Teil des Buches. Im Grunde möchte ich zwei Dinge über den folgenden Code wissen:

package main

import (
    "fmt"
    "runtime"
    "sync"
    "time"
)

var counter int = 0
var wg sync.WaitGroup
var mtx sync.Mutex

func main() {
    wg.Add(2)

    runtime.GOMAXPROCS(1)

    go incCounter("A")
    go incCounter("B")

    wg.Wait()
    fmt.Println(counter)
}

func incCounter(prefix string) {
    fmt.Println("Started thread ", prefix)
    defer wg.Done()
    mtx.Lock()
    {
        fmt.Println("Incrementing counter from ", prefix)
        counter = counter + 1
        fmt.Println("Passing to another thread")
        runtime.Gosched()
        for i := 1; i < 100; i++ {
            time.Sleep(1 * time.Second)
            fmt.Println("Thread still executing ", prefix)
        }
    }
    mtx.Unlock()
}

Die Ausgabe ist:

Started thread  B
Incrementing counter from  B
Passing to another thread
Started thread  A
Thread still executing  B
Thread still executing  B
Thread still executing  B
Thread still executing  B
  1. Warum wird Goroutine B zuerst ausgeführt? Da im Code Goroutine A an erster Stelle steht, möchte ich, dass sie auch zuerst ausgeführt wird.
  2. goroutine B verwendet die .Gosched-Methode, um Goroutine A mit der Ausführung beginnen zu lassen. Da der Mutex jedoch gesperrt ist, wartet Goroutine A darauf, dass er entsperrt wird. Zu diesem Zeitpunkt habe ich GOMAXPROCS so eingestellt, dass es nur einen logischen Prozessor hat. Warum scheinen die beiden Goroutinen parallel zu laufen? Sollte das wirklich passieren?

Wie gesagt, wenn man gomaxprox auf 1 setzt, kann immer nur eine Goroutine gleichzeitig ausgeführt werden, aber in diesem Fall scheint das nicht der Fall zu sein, tatsächlich laufen beide Goroutinen parallel.

Lösung

Goroutinen laufen gleichzeitig. Das heißt, wenn Prozessoren verfügbar sind, kann der Scheduler deren parallele Ausführung einplanen. Wenn nur ein Prozessor verfügbar ist, werden sie trotzdem gleichzeitig ausgeführt, es wird jedoch immer nur eine Goroutine ausgeführt.

Die Go-Laufzeit gibt keine Garantie dafür, welche Goroutine zuerst ausgeführt wird. Die Reihenfolge einer Reihe neu erstellter Goroutinen ist also zufällig,

Das obige ist der detaillierte Inhalt vonWarum verhält sich die Go-Routine so?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen