Heim  >  Artikel  >  Backend-Entwicklung  >  Eine ausführliche Einführung in die Verwendung des Golang-Kontexts

Eine ausführliche Einführung in die Verwendung des Golang-Kontexts

PHPz
PHPzOriginal
2023-04-11 09:14:041211Durchsuche

Golang ist eine leistungsstarke Programmiersprache mit Effizienz und Einfachheit und entwickelt sich derzeit rasant weiter. Beim Schreiben von Go-Code haben die Eingabe- und Ausgabeparameter jeder Funktion ihren eigenen Lebenszyklus. Wenn mehrere Goroutinen gleichzeitig ausgeführt werden, müssen wir möglicherweise den Kontext verwalten, um die Korrektheit des Programms sicherzustellen. Dies ist die Rolle des Golang-Kontexts. In diesem Artikel stellen wir die Verwendung des Golang-Kontexts vor.

1. Das Konzept von Golang Context

Golang Context ist ein Objekt, das relevante Werte innerhalb des Anforderungsbereichs enthält. Dieses Objekt kann zwischen Funktionen übergeben werden und unterstützt Abbruchvorgänge. Wenn wir beispielsweise HTTP-Anforderungen verarbeiten, können wir das Kontextpaket verwenden, um die HTTP-Anforderung als Parameter zu übergeben und den anforderungsbezogenen Kontext abzurufen.

Die Strukturdefinition von Golang Context lautet wie folgt:

type Context interface {
    Deadline() (deadline time.Time, ok bool)
    Done() <-chan struct{}
    Err() error
    Value(key interface{}) interface{}
}

Die Definition der obigen Struktur umfasst die Methoden Deadline, Done, Err und Value. Im Folgenden stellen wir ihre Funktionen einzeln vor.

2. Verwendung des Golang-Kontexts

  1. Deadline-Methode

Deadline-Methode gibt eine Zeit und einen booleschen Wert zurück. Wenn der Kontext abgebrochen wird oder seine Frist erreicht, gibt der Kontext dieses Mal und den booleschen Wert „true“ zurück, andernfalls gibt er „false“ zurück. In einigen Kontexten gibt es keine Frist. In diesem Fall gibt die Deadline-Methode „false“ zurück.

func main() {
    ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(time.Second*5))
    defer cancel()
    
    select {
    case <-time.After(3 * time.Second):
        fmt.Println("等待了3秒钟")
    case <-ctx.Done():
        fmt.Println(ctx.Err())
    }
}

Im obigen Code erstellen wir zunächst einen Kontext mit einer Frist, deren Frist 5 Sekunden nach der aktuellen Zeit liegt. Dann verwenden wir die Select-Anweisung, um 3 Sekunden zu warten. Zu diesem Zeitpunkt werden wir feststellen, dass das Programm noch wartet, da die Wartezeit die Frist nicht überschreitet. Wenn schließlich die Frist überschritten wird, wird das Programm aufgrund des Rückgabewerts von ctx.Done() beendet.

  1. Done-Methode

Done-Methode gibt einen schreibgeschützten Kanal zurück. Wenn der Kontext abgebrochen wird oder die Frist erreicht, wird dieser Kanal geschlossen. Daher können wir die Select-Anweisung und die Done-Methode in unserem Code verwenden, um den Status des Kontexts zu überwachen.

func main() {
    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()

    go func(ctx context.Context) {
        for {
            select {
            case <-ctx.Done():
                fmt.Println(ctx.Err())
                return
            default:
                fmt.Println("goroutine正在运行中...")
                time.Sleep(1 * time.Second)
            }
        }
    }(ctx)

    // 模拟耗时操作
    time.Sleep(5 * time.Second)
    cancel() // 取消Context
    time.Sleep(3 * time.Second)
    fmt.Println("main函数执行结束")
}

Im obigen Code verwenden wir die Funktionen WithCancel und cancel, um den Kontext zu starten und zu beenden, und drucken regelmäßig Protokolle in einer Goroutine, bis der Kontext abgebrochen wird. Gleichzeitig simulieren wir mit Sleep einen zeitaufwändigen Vorgang. Die aktuelle Funktion ruft nach 5 Sekunden die Abbruchfunktion auf, beendet den Kontext und beendet damit das gesamte Programm.

  1. Err-Methode

Err-Methode gibt den Grund zurück, warum der Kontext abgebrochen wurde. Bei einem abgebrochenen Kontext gibt diese Methode einen Fehlerwert ungleich Null zurück. Wenn der Kontext nicht abgebrochen wurde, gibt die Err-Methode Null zurück.

func main() {
    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()

    go func(ctx context.Context) {
        for {
            select {
            case <-ctx.Done():
                fmt.Println(ctx.Err())
                return
            default:
                fmt.Println("goroutine正在运行中...")
                time.Sleep(1 * time.Second)
            }
        }
    }(ctx)

    // 模拟耗时操作
    time.Sleep(5 * time.Second)
    cancel() // 取消Context
    time.Sleep(3 * time.Second)
    fmt.Println("main函数执行结束")
}

Im obigen Code wird die Err-Methode in der Goroutine verwendet, die den Grund für den Abbruch zurückgibt. Abschließend geben wir in der Hauptfunktion „Hauptfunktionsausführung beendet“ aus.

  1. Value-Methode

Value-Methode gibt den mit Context verknüpften Wert zurück, der ein Objekt vom Typ interface{} ist. Sie können im Kontext einen beliebigen Werttyp festlegen und die Value-Methode verwenden, um den Wert in nachfolgenden Vorgängen abzurufen.

type authKey string
func main() {
    ctx := context.WithValue(context.Background(), authKey("token"), "123456")
    fmt.Println(ctx.Value(authKey("token"))) // 打印"123456"
}

Im obigen Code verwenden wir die WithValue-Methode, um einen Zeichenfolgenwert mit dem Kontext zu verknüpfen, und verwenden die Value-Methode, um den Wert zu erhalten.

3. Zusammenfassung

Der Golang-Kontext ist ein wichtiger Teil des Umgangs mit gleichzeitigem Code. Durch die Weitergabe von Kontext zwischen Funktionen können wir den Lebenszyklus im Code verwalten und den Status von Kontext auch über Methoden wie „Done“, „Err“ und „Value“ überwachen. Wenn Sie die Verwendung von Golang Context beherrschen, können Sie die Qualität und Parallelität Ihres Codes verbessern.

Das obige ist der detaillierte Inhalt vonEine ausführliche Einführung in die Verwendung des Golang-Kontexts. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn