Maison >développement back-end >Golang >Comment garantir que les routines Go sont terminées avant les sorties principales ?

Comment garantir que les routines Go sont terminées avant les sorties principales ?

DDD
DDDoriginal
2024-12-09 16:33:14778parcourir

How to Ensure Go Routines Complete Before Main Exits?

En attente de la fin de la routine Go

Dans Go, une pratique courante consiste à utiliser des goroutines pour effectuer des tâches simultanées. Pour garantir que le programme principal attend la fin de toutes les goroutines avant de quitter, il est crucial de mettre en œuvre des mécanismes de synchronisation appropriés.

Une approche, comme mentionné dans la question, consiste à utiliser un canal booléen (done) :

func do_stuff(done chan bool) {
    fmt.Println("Doing stuff")
    done <- true
}
func main() {
    fmt.Println("Main")
    done := make(chan bool)
    go do_stuff(done)
    <-done
}

Pourquoi <-done Fonctionne :

L'opération <-done est une réception de canal bloquante. Il attend qu'une valeur soit envoyée sur le canal terminé. Dans le code fourni, do_stuff envoie true sur le canal une fois la tâche terminée, ce qui entraîne le succès de l'opération <-done dans main.

Impasse due à la décommentation de la dernière ligne :

Décommenter la dernière ligne de main conduit à une impasse :

func main() {
    fmt.Println("Main")
    done := make(chan bool)
    go do_stuff(done)
    <-done
    // <-done
}

Cette deuxième opération <-done tente de lire à partir d'un canal vide sans qu'aucune goroutine ne lui envoie de valeurs. En conséquence, le programme se bloque dans une impasse.

Méthode de synchronisation alternative utilisant le package sync :

Pour des scénarios plus complexes, le package sync propose des primitives de synchronisation alternatives. Dans le code fourni, sync.WaitGroup peut efficacement suivre l'achèvement des goroutines :

package main

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

func main() {
    var wg sync.WaitGroup
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go func() {
            longOp()
            wg.Done()
        }()
    }
    // will wait until wg.Done is called 10 times (10 goroutines finish)
    wg.Wait()
}

func longOp() {
    time.Sleep(time.Second * 2)
    fmt.Println("long op done")
}

L'utilisation de sync.WaitGroup garantit que main attend la fin des 10 goroutines avant de quitter le programme.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn