Interblocage dans Go : groupe d'attente et canaux tamponnés
Dans Go, un blocage se produit lorsque des goroutines concurrentes attendent indéfiniment la fin de l'autre. Une cause fréquente de blocage implique l'utilisation de WaitGroups et de canaux mis en mémoire tampon.
Exemple de blocage
Considérez le code suivant :
<code class="go">package main import "fmt" import "sync" func main() { ch := make(chan []int, 4) var m []int var wg sync.WaitGroup for i := 0; i < 5; i++ { wg.Add(1) go func() { defer wg.Done() ch <- m // Sending to a full channel return }() } wg.Wait() for c := range ch { fmt.Printf("c is %v", c) } }</code>
Ce code vise à envoyer 5 tranches vides à un canal tamponné d'une capacité de 4, puis à lire à partir du canal une fois toutes les goroutines terminées. Cependant, le code entraîne une erreur de blocage.
Cause du blocage
Le blocage est dû à deux problèmes :
Solution
Pour résoudre l'impasse, effectuez l'une des modifications suivantes :
Solution 1 :
Augmentez la capacité du canal à 5 (ou plus) et fermez-le après l'envoi de toutes les données :
<code class="go">ch := make(chan []int, 5) ... wg.Wait() close(ch)</code>
Solution 2 :
Démarrez une goroutine distincte pour lire à partir du canal et avertissez la goroutine principale lorsque toutes les données ont été reçues :
<code class="go">func main() { ch := make(chan []int, 4) var m []int var wg sync.WaitGroup for i := 0; i < 5; i++ { wg.Add(1) go func() { ch <- m wg.Done() }() } go func() { for c := range ch { fmt.Printf("c is %v\n", c) wg.Done() } }() wg.Wait() }</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!