Délai d'expiration pour WaitGroup.Wait() : approches idiomatiques
Dans Go, une limite de temps peut être définie pour WaitGroup.Wait() pour éviter une attente infinie pour les travailleurs errants . Voici une exploration détaillée des façons idiomatiques de la mettre en œuvre et des approches alternatives.
Solution recommandée : utiliser une minuterie et un canal
L'approche suivante est largement considérée comme la solution la plus idiomatique :
import (
"sync"
"time"
)
func waitTimeout(wg *sync.WaitGroup, timeout time.Duration) bool {
c := make(chan struct{})
go func() {
wg.Wait()
close(c)
}()
select {
case <-c:
return false // completed normally
case <-time.After(timeout):
return true // timed out
}
}
Copier après la connexion
- Un canal (c) est créé pour signaler quand le groupe d'attente termine son attente.
- Une goroutine est générée pour appeler wg.Wait() et fermer le canal une fois terminé.
- Une instruction select écoute soit le canal soit fermé, soit un délai d'attente.
- Si le canal est fermé, la fonction renvoie false, indiquant un achèvement normal.
- Si le le délai d'attente est atteint, la fonction renvoie vrai, ce qui signifie un délai d'attente.
Simplification de la solution recommandée
Pour une implémentation plus simple, considérez ce qui suit :
- Fermez le canal pour signaler l'achèvement au lieu d'envoyer une valeur.
- Utilisez defer pour fermer le canal même si la fonction se termine prématurément.
- Supprimez le groupe d'attente si une seule tâche doit être attendue .
- Utilisez des durées directement sans conversions (par exemple, time.Second).
Approche alternative : utiliser un contexte annulable
Une approche alternative consiste à utiliser un contexte annulable contexte :
import (
"context"
"sync/atomic"
"sync"
)
func waitWithCancel(ctx context.Context, wg *sync.WaitGroup) bool {
ctxDone := make(chan struct{})
var exited int32
go func() {
defer close(ctxDone)
wg.Wait()
atomic.StoreInt32(&exited, 1)
}()
select {
case <-ctx.Done():
return atomic.LoadInt32(&exited) == 0
case <-ctxDone:
return true
}
}
Copier après la connexion
- Un contexte annulable (ctx) est créé.
- Un canal (ctxDone) est utilisé pour signaler lorsque le contexte est annulé.
- Une goroutine est générée pour attendre le groupe d'attente et signaler le canal ctxDone.
- Une instruction select écoute soit le contexte à annuler, soit le groupe d'attente à terminer.
- Si le contexte est annulée, la fonction revient selon que le groupe d'attente a déjà terminé son attente.
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!