Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bagaimana untuk Menamatkan Goroutine dengan Anggun dan Mengendalikan Ralat dalam Go?

Bagaimana untuk Menamatkan Goroutine dengan Anggun dan Mengendalikan Ralat dalam Go?

Mary-Kate Olsen
Mary-Kate Olsenasal
2024-11-12 07:21:02918semak imbas

How to Gracefully Terminate Goroutines and Handle Errors in Go?

Penamatan Goroutine Idiomatik dan Pengendalian Ralat: Kajian Kes

Dalam Go, pengendalian penamatan goroutine selalunya menjadi cabaran bagi pembangun. Satu isu biasa ialah memastikan pembersihan goroutine dengan betul apabila ralat berlaku. Artikel ini menunjukkan penyelesaian yang elegan dan idiomatik untuk masalah ini menggunakan pengelompokan ralat.

Pertimbangkan contoh berikut:

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
}

Pelaksanaan ini mempunyai kelemahan kritikal: ia membocorkan goroutine. Penyelesaiannya ialah menggunakan kumpulan ralat:

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()
}

Kumpulan ralat secara automatik menunggu semua gorout selesai dengan jayanya atau membatalkan yang tinggal sekiranya berlaku ralat. Dalam kes di atas, goroutine pertama yang menghadapi ralat mencetuskan pembatalan semua yang lain, dan ralat itu disebarkan kembali kepada pemanggil. Penggunaan konteks memastikan penamatan yang anggun apabila konteks sekeliling dibatalkan.

Atas ialah kandungan terperinci Bagaimana untuk Menamatkan Goroutine dengan Anggun dan Mengendalikan Ralat dalam Go?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn