Maison >développement back-end >Golang >Comment résoudre « Erreur fatale : tous les goroutines sont endormis - impasse ! » dans Go lors de l'utilisation de canaux sans tampon ?

Comment résoudre « Erreur fatale : tous les goroutines sont endormis - impasse ! » dans Go lors de l'utilisation de canaux sans tampon ?

Barbara Streisand
Barbara Streisandoriginal
2024-11-25 15:36:17706parcourir

 How to Resolve

"Go : Erreur fatale : tous les Goroutines sont endormis - Impasse"

Problème :

Vous disposez d'un fichier texte contenant une seule ligne de mots et vous essayez de stocker chaque mot dans une chaîne. Par la suite, vous souhaitez récupérer ces mots du canal et les imprimer un par un. L'extrait de code suivant représente votre approche actuelle :

package main

import (
    "bufio"
    "fmt"
    "os"
)

func main() {
    f, _ := os.Open("D:\input1.txt")
    scanner := bufio.NewScanner(f)
    file1chan := make(chan string)

    for scanner.Scan() {
        line := scanner.Text()
        parts := strings.Fields(line)

        for i := range parts {
            file1chan <- parts[i]
        }
    }
    print(file1chan)
}

func print(in <-chan string) {
    for str := range in {
        fmt.Printf("%s\n", str)
    }
}

Cependant, lors de l'exécution de ce code, vous rencontrez le message d'erreur : "Erreur fatale : toutes les goroutines sont endormies - blocage !"

Solution :

L'erreur survient car votre file1chan est un canal sans tampon. Lorsque vous essayez d'envoyer une valeur sur ce canal, celui-ci se bloque indéfiniment, en attendant un récepteur. Pour résoudre ce blocage, vous pouvez soit démarrer une nouvelle goroutine chargée d'envoyer les valeurs dans le canal, soit déclarer le canal comme mis en mémoire tampon. Deux approches sont décrites ci-dessous :

Utilisation d'un nouveau Goroutine :

package main

import (
    "bufio"
    "fmt"
    "os"
)

func main() {
    f, _ := os.Open("D:\input1.txt")
    scanner := bufio.NewScanner(f)
    file1chan := make(chan string)

    // Start a new goroutine to send strings down file1chan
    go func() {
        for scanner.Scan() {
            line := scanner.Text()
            parts := strings.Fields(line)

            for i := range parts {
                file1chan <- parts[i]
            }
        }
        close(file1chan) // Close the channel when done sending.
    }()

    print(file1chan) // Read strings from file1chan
}

func print(in <-chan string) {
    for str := range in {
        fmt.Printf("%s\n", str)
    }
}

Utilisation d'un canal tamponné :

Pour gérant une seule chaîne, vous pouvez définir un canal tamponné de taille 1 :

package main

import (
    "bufio"
    "fmt"
    "os"
)

func main() {
    f, _ := os.Open("D:\input1.txt")
    scanner := bufio.NewScanner(f)
    file1chan := make(chan string, 1) // Buffer size of one

    for scanner.Scan() {
        line := scanner.Text()
        parts := strings.Fields(line)

        for i := range parts {
            file1chan <- parts[i]
        }
    }

    close(file1chan) // Close the channel when done sending.
    print(file1chan)
}

func print(in <-chan string) {
    for str := range in { // Read all values until channel gets closed
        fmt.Printf("%s\n", str)
    }
}

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