Maison > développement back-end > Golang > le corps du texte

Pourquoi le programme go suivant donne-t-il une erreur de blocage 'Erreur fatale : toutes les goroutines dorment - blocage !'

PHPz
Libérer: 2024-02-09 08:00:11
avant
451 Les gens l'ont consulté

为什么下面的 go 程序会出现死锁错误“致命错误:所有 goroutine 都在睡眠 - 死锁!”

En langage Go, le blocage est une erreur courante Lorsque toutes les goroutines dorment, une erreur fatale se produit : "Erreur fatale : toutes les goroutines dorment - blocage !". Cette situation se produit généralement lorsque plusieurs goroutines s'attendent. Lorsqu'une goroutine attend qu'une autre goroutine termine une opération et qu'une autre goroutine attend que la première goroutine termine une opération, une impasse se produit. Dans ce cas, le programme ne peut pas continuer à s'exécuter car toutes les goroutines ne peuvent pas continuer à s'exécuter. Afin d'éviter les erreurs de blocage, nous devons concevoir et gérer soigneusement les dépendances entre les goroutines pour garantir qu'elles peuvent fonctionner correctement ensemble.

Contenu de la question

Je suis nouveau sur Golang et j'essaie d'utiliser certains producteurs-consommateurs typiques de chaînes. Je comprends que le producteur et le consommateur doivent écrire et lire à partir du même canal. Mais juste pour expérimenter, je leur ai demandé d'écrire et de lire sur différents canaux, comme indiqué ci-dessous

package main
    
    import (
        "fmt"
        "sync"
    )
    
    func main() {
    
        var wg sync.WaitGroup
        wg.Add(2)
    
        fmt.Println("Starting the main application")
    
        channel :=make( chan int)
        channel1 :=make( chan int)
    
    
        go generateNumbersV2(&wg, channel)
        go printNumbersV2(&wg, channel1)
    
    
        fmt.Println("Waiting for other goroutines")
        wg.Wait()
        //close()
        //close(channel)
    
        fmt.Println("All goroutines finished")
    }
    
    func printNumbersV2(wg *sync.WaitGroup, rc <-chan int) {
        defer wg.Done()
    
        for idx:=0 ;idx<3;idx++ {
    
            val := <-rc
            fmt.Println("******value received from channel ",val)
        }
    }
    
    func generateNumbersV2(wg *sync.WaitGroup, wc chan<- int) {
        defer wg.Done()
    
        for idx:=0 ;idx<3;idx++ {
    
             wc<-idx
            fmt.Println("###value written to channel ",idx)
        }
    
    }
Copier après la connexion

Lorsque j'exécute le programme, j'obtiens l'erreur suivante.

fatal error: all goroutines are asleep - deadlock!
Copier après la connexion

Maintenant, même si je sais que les deux goroutines sont bloquées, l'une sur l'appel de lecture au canal 1 et l'autre sur l'appel d'écriture au canal, donc le programme ne se termine jamais. Mais ma question est la suivante : s'il attend réellement une valeur dans ces canaux, le programme ne devrait-il pas attendre indéfiniment au lieu de le déclarer dans une impasse ? Et si plus tard, en raison d'une lecture/écriture sur le réseau, les valeurs arrivaient et que d'autres écritures de routine allaient sur ces canaux ?

Solution de contournement

Un programme en cours d'exécution se terminera par une panique de blocage uniquement lorsque toutes les goroutines seront bloquées sur les primitives de synchronisation. Si toutes les goroutines sont bloquées en attente d'opérations de canal et/ou de verrouillages mutex, la réception réseau n'est pas possible car aucune goroutine n'écoute les connexions réseau. Cela signifie également que dans un programme comportant de nombreux goroutines, vous pouvez avoir de nombreux groupes de goroutines bloqués, mais le programme continue de s'exécuter car il existe d'autres goroutines qui peuvent toujours continuer à s'exécuter.

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!

Étiquettes associées:
source:stackoverflow.com
Déclaration de ce site Web
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal