Maison >développement back-end >Golang >Comment résoudre les blocages de Go Concurrency : « toutes les goroutines sont endormies » ?

Comment résoudre les blocages de Go Concurrency : « toutes les goroutines sont endormies » ?

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-12-28 13:31:13857parcourir

How to Resolve Go Concurrency Deadlocks:

Erreur de blocage dans la concurrence : "lancer : tous les Goroutines sont endormis"

Lorsque vous travaillez avec la concurrence dans Go, un blocage peut se produire si tous les goroutines s'attendent pour effectuer une action. Une erreur courante associée à ce problème est « lancer : toutes les goroutines sont endormies - impasse ! »

Comprendre le problème

Considérez le programme Go suivant :

package main

import (
    "fmt"
)

func total(ch chan int) {
    res := 0
    for iter := range ch {
        res += iter
    }
    ch <- res
}

func main() {
    ch := make(chan int)
    go total(ch)
    ch <- 1
    ch <- 2
    ch <- 3
    fmt.Println("Total is ", <-ch)
}

Lors de l'exécution de ce programme, nous rencontrons l'erreur "throw : all goroutines are sleep - deadlock !" La raison en est que la boucle de plage dans la fonction total ne se terminera jamais car nous ne fermons jamais le canal ch. En conséquence, la goroutine en attente de recevoir le résultat dans la fonction principale ne le recevra jamais.

Résoudre l'impasse

Pour sortir de cette impasse, nous devons fermer le canal ch pour indiquer qu’aucune autre valeur ne sera envoyée. De plus, nous pouvons utiliser un canal distinct pour renvoyer le résultat, empêchant ainsi un envoi et une réception directs sur le même canal.

Le programme révisé ci-dessous résout ces problèmes :

package main

import (
    "fmt"
)

func total(in chan int, out chan int) {
    res := 0
    for iter := range in {
        res += iter
    }
    out <- res // sends back the result
}

func main() {
    ch := make(chan int)
    rch := make(chan int)
    go total(ch, rch)
    ch <- 1
    ch <- 2
    ch <- 3
    close(ch) // this will end the loop in the total function
    result := <-rch // waits for total to give the result
    fmt.Println("Total is ", result)
}

En terminant le canal ch et en utilisant un canal rch séparé pour le résultat, nous éliminons le blocage et permettons au programme de s'exécuter correctement.

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