Comment arrêter gracieusement une routine Go
Dans Go, les goroutines offrent une concurrence légère, mais il peut être difficile de les terminer gracieusement. Cette question répond à la nécessité d'envoyer un signal à une goroutine pour arrêter son exécution.
Le code fourni démontre une tentative d'arrêt d'une goroutine en définissant un indicateur booléen (trop tard) sur vrai. Cependant, cette approche est problématique car la lecture depuis un canal bloque la goroutine.
Solution 1 : Utiliser un canal supplémentaire
La solution implique d'utiliser un deuxième canal (trop tard) pour communiquer le signal d'arrêt. Ce canal reste ouvert même lorsque la goroutine ne le lit pas activement.
<code class="go">func main() { tooLate := make(chan struct{}) // Unbuffered channel for stop signal proCh := make(chan string) go func() { for { fmt.Println("working") time.Sleep(1 * time.Second) select { case <-tooLate: fmt.Println("stopped") return case proCh <- "processed": // Non-blocking send default: // Allows the goroutine to continue without blocking } fmt.Println("done here") } }() select { case proc := <-proCh: fmt.Println(proc) case <-time.After(1 * time.Second): fmt.Println("too late") close(tooLate) // Signal to goroutine to stop } time.Sleep(4 * time.Second) fmt.Println("finish\n") }</code>
Dans cette solution, lorsque le délai expire, le canal trop tard est fermé, ce qui amène la goroutine à quitter son instruction de sélection de blocage et retour.
Solution 2 : Utilisation de sync.Cond
Vous pouvez également utiliser le type sync.Cond pour implémenter un mécanisme de signalisation plus sophistiqué. Voici un exemple :
<code class="go">func main() { var stopped bool cond := sync.NewCond(new(sync.Mutex)) go func() { for { cond.L.Lock() defer cond.L.Unlock() if stopped { fmt.Println("stopped") return } fmt.Println("working") cond.Wait() // Wait for the signal to stop } }() time.Sleep(1 * time.Second) cond.Signal() // Send the stop signal time.Sleep(4 * time.Second) fmt.Println("finish\n") }</code>
Avec cette approche, la goroutine attend la méthode cond.Wait() jusqu'à ce qu'elle reçoive un signal de cond.Signal().
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!