Délai d'expiration pour WaitGroup.Wait()
WaitGroup.Wait() peut se bloquer indéfiniment, en attendant que toutes les goroutines soient terminées. Cela peut être problématique lorsque vous souhaitez protéger votre système contre les travailleurs errants qui pourraient bloquer l'exécution indéfiniment. Bien qu'il n'existe pas de moyen idiomatique de définir un délai d'attente pour WaitGroup.Wait(), il existe plusieurs approches pour obtenir cette fonctionnalité.
Une approche courante consiste à utiliser un canal et une goroutine. Lorsque la goroutine termine son travail, elle envoie un signal au canal. Le programme principal peut sélectionner le canal et une minuterie pour déterminer si le goroutine a expiré. Voici un exemple :
import ( "sync" "time" ) func main() { var wg sync.WaitGroup wg.Add(1) timeout := time.After(5 * time.Second) ch := make(chan struct{}) go func() { defer wg.Done() defer close(ch) // Do some work }() select { case <-ch: // Goroutine finished before timeout wg.Wait() // Wait for all goroutines to finish case <-timeout: // Goroutine timed out wg.Wait() // Block until all goroutines have completed log.Println("Timeout occurred") } }
Cette solution utilise une instruction select pour attendre soit sur le canal, soit sur une minuterie, fournissant un mécanisme de délai d'attente pour WaitGroup.Wait(). D'autres optimisations recommandées incluent l'utilisation d'instructions defer pour fermer les canaux et l'utilisation de constantes non typées pour les durées d'expiration.
Vous pouvez également utiliser une fonction d'assistance personnalisée qui enveloppe la fonctionnalité ci-dessus, simplifiant le code et le rendant plus réutilisable. Voici un exemple :
func waitTimeout(wg *sync.WaitGroup, timeout time.Duration) bool { c := make(chan struct{}) defer close(c) go func() { wg.Wait() c <- struct{}{} }() select { case <-c: return false // Completed normally case <-time.After(timeout): return true // Timed out } }
Cette fonction peut être utilisée comme suit :
if waitTimeout(&wg, 5*time.Second) { fmt.Println("Timed out waiting for wait group") } else { fmt.Println("Wait group finished") }
Ces approches fournissent un moyen de définir un délai d'attente pour WaitGroup.Wait(), vous permettant de sauvegarder votre système contre les travailleurs errants bloquant l'exécution indéfiniment.
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!