Heim  >  Artikel  >  Backend-Entwicklung  >  Wie kann man Goroutinen ordnungsgemäß beenden und Fehler in Go behandeln?

Wie kann man Goroutinen ordnungsgemäß beenden und Fehler in Go behandeln?

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-11-12 07:21:02926Durchsuche

How to Gracefully Terminate Goroutines and Handle Errors in Go?

Idiomatische Goroutine-Beendigung und Fehlerbehandlung: Eine Fallstudie

In Go ist die Handhabung der Goroutine-Beendigung oft eine Herausforderung für Entwickler. Ein häufiges Problem besteht darin, sicherzustellen, dass Goroutinen ordnungsgemäß bereinigt werden, wenn ein Fehler auftritt. Dieser Artikel zeigt eine elegante und idiomatische Lösung für dieses Problem mithilfe der Fehlergruppierung.

Betrachten Sie das folgende Beispiel:

package main

import (
        "sync"
        "time"
)

func fetchAll() error {
        wg := sync.WaitGroup{}
        errs := make(chan error)

        // run all the http requests in parallel
        for i := 0; i < 4; i++ {
                wg.Add(1)
                go func(i int) {
                        defer wg.Done()

                        // pretend this does an http request and returns an error
                        time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond)
                        errs <- fmt.Errorf("goroutine %d's error returned", i)
                }(i)
        }

        // wait until all the fetches are done and close the error
        // channel so the loop below terminates
        go func() {
                wg.Wait()
                close(errs)
        }()

        // return the first error
        for err := range errs {
                if err != nil {
                        return err
                }
        }

        return nil
}

Diese Implementierung weist einen kritischen Fehler auf: Sie lässt Goroutinen durchsickern. Die Lösung besteht darin, eine Fehlergruppe zu verwenden:

package main

import (
        "context"
        "fmt"
        "math/rand"
        "time"

        "golang.org/x/sync/errgroup"
)

func fetchAll(ctx context.Context) error {
        errs, ctx := errgroup.WithContext(ctx)

        // run all the http requests in parallel
        for i := 0; i < 4; i++ {
                errs.Go(func() error {
                        // pretend this does an http request and returns an error                                                  
                        time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond)                                               
                        return fmt.Errorf("error in go routine, bailing")                                                      
                })
        }

        // Wait for completion and return the first error (if any)                                                                 
        return errs.Wait()
}

Eine Fehlergruppe wartet automatisch darauf, dass alle Goroutinen erfolgreich abgeschlossen werden, oder bricht im Falle eines Fehlers die verbleibenden ab. Im obigen Fall löst die erste Goroutine, die auf einen Fehler stößt, den Abbruch aller anderen aus, und der Fehler wird an den Aufrufer zurückgegeben. Die Verwendung von Kontext gewährleistet eine ordnungsgemäße Beendigung, wenn der umgebende Kontext abgebrochen wird.

Das obige ist der detaillierte Inhalt vonWie kann man Goroutinen ordnungsgemäß beenden und Fehler in Go behandeln?. 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