Maison > Article > développement back-end > Pourquoi l'utilisation de sync.WaitGroup avec des fonctions externes entraîne-t-elle une impasse ?
Dans un programme, vous pouvez rencontrer des problèmes lors de l'utilisation de sync.WaitGroup avec des fonctions définies en dehors de la fonction principale. Explorons cette situation.
Problème :
Considérez le code suivant :
<code class="go">package main import ( "fmt" "sync" ) func main() { ch := make(chan int) var wg sync.WaitGroup wg.Add(2) go Print(ch, wg) // go func(){ for i := 1; i <= 11; i++ { ch <- i } close(ch) defer wg.Done() }() wg.Wait() //deadlock here } // Print prints all numbers sent on the channel. // The function returns when the channel is closed. func Print(ch <-chan int, wg sync.WaitGroup) { for n := range ch { // reads from channel until it's closed fmt.Println(n) } defer wg.Done() }</code>
Ici, vous visez que le programme imprime des nombres à partir de 1 à 11, mais il n'imprime parfois que 1 à 10.
Analyse des erreurs :
Vous transmettez une copie de sync.WaitGroup à la fonction d'impression, qui signifie qu'il n'appelle pas la méthode Done() sur le sync.WaitGroup que vous attendez dans la fonction principale.
Solution :
Pour résoudre ce problème , mettez à jour le code comme suit :
<code class="go">package main import ( "fmt" "sync" ) func main() { ch := make(chan int) var wg sync.WaitGroup wg.Add(2) go Print(ch, &wg) go func() { for i := 1; i <= 11; i++ { ch <- i } close(ch) defer wg.Done() }() wg.Wait() //deadlock here } func Print(ch <-chan int, wg *sync.WaitGroup) { for n := range ch { // reads from channel until it's closed fmt.Println(n) } defer wg.Done() }</code>
Cela garantit que la fonction Print appelle la méthode Done() sur le même sync.WaitGroup que vous attendez dans la fonction principale.
Vous pouvez également restructurer votre code pour supprimer la dépendance à l'égard de sync.WaitGroup dans la fonction Imprimer :
<code class="go">package main import ( "fmt" ) func main() { ch := make(chan int) go func() { for i := 1; i <= 11; i++ { ch <- i } close(ch) }() for n := range ch { // reads from channel until it's closed fmt.Println(n) } }</code>
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!