Maison  >  Article  >  développement back-end  >  Pourquoi le programme go suivant donne-t-il une erreur de blocage "Erreur fatale : toutes les goroutines dorment - blocage !"

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

PHPz
PHPzavant
2024-02-09 08:00:11401parcourir

为什么下面的 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)
        }
    
    }

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

fatal error: all goroutines are asleep - deadlock!

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!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer