Maison > Article > développement back-end > Pourquoi les chaînes Go provoquent-elles des blocages et comment pouvons-nous les éviter ?
Canaux Go et blocages : comprendre le problème de blocage
Lorsque vous travaillez avec les canaux Go, des blocages peuvent survenir si une synchronisation appropriée n'est pas assurée. Prenons l'exemple suivant :
<code class="go">func main() { c1 := make(chan int) c2 := make(chan int) // Create two goroutines that ping-pong values between channels go func() { for i := range c1 { println("G1 got", i) c2 <- i } }() go func() { for i := range c2 { println("G2 got", i) c1 <- i } }() // Send an initial value to start the chain c1 <- 1 // Wait for a long time to observe the ping-ponging behavior time.Sleep(1000000000 * 50) }</code>
Ce code imprime avec succès les valeurs indéfiniment jusqu'à ce que la fonction principale se termine. Cependant, si une autre valeur est envoyée à l'un des canaux, un blocage se produit :
<code class="go">func main() { c1 := make(chan int) c2 := make(chan int) // Create two goroutines to ping-pong values between channels go func() { for i := range c1 { println("G1 got", i) c2 <- i } }() go func() { for i := range c2 { println("G2 got", i) c1 <- i } }() // Send an initial value to start the chain c1 <- 1 // Wait for a short time time.Sleep(1000000000 * 1) // Send another value to the channel c1 <- 2 // Wait for a long time to observe the issue time.Sleep(1000000000 * 50) }</code>
Dans ce cas, la sortie reste bloquée après l'envoi de la valeur "2" :
G1 got 1 G2 got 1 G1 got 1 G2 got 1 G1 got 2
Ce problème se produit parce que les goroutines attendent les unes des autres pour recevoir les valeurs de leurs canaux respectifs. Par conséquent, aucune des deux goroutines ne peut progresser et un blocage se produit.
Pour éviter les blocages, assurez-vous que les canaux sont correctement synchronisés. Une approche consiste à utiliser des canaux tamponnés avec une capacité non nulle, comme dans l'exemple suivant :
<code class="go">// ... (Same code as before) c1 := make(chan int, 1) // Buffered channel with capacity of 1 c2 := make(chan int, 1)</code>
Avec les canaux tamponnés, une goroutine peut envoyer une valeur même si l'autre goroutine n'a pas encore reçu la précédente. un. Cela permet d'éviter les impasses dans des situations comme celle décrite.
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!