Maison  >  Article  >  développement back-end  >  Pourquoi les chaînes Go provoquent-elles des blocages et comment pouvons-nous les éviter ?

Pourquoi les chaînes Go provoquent-elles des blocages et comment pouvons-nous les éviter ?

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-11-02 09:50:03394parcourir

Why Do Go Channels Cause Deadlocks and How Can We Prevent Them?

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn