Maison >développement back-end >Golang >Pourquoi une routine Infinite Go empêche-t-elle d'autres Goroutines d'envoyer vers des canaux ?

Pourquoi une routine Infinite Go empêche-t-elle d'autres Goroutines d'envoyer vers des canaux ?

Linda Hamilton
Linda Hamiltonoriginal
2024-12-04 16:52:11555parcourir

Why Does an Infinite Go Routine Block Other Goroutines from Sending to Channels?

La routine Go bloque les autres : une explication plus approfondie

Dans Go, le code suivant présente un comportement inhabituel où une goroutine avec une boucle infinie semble empêche le message d'une autre goroutine d'atteindre le canal prévu :

func main() {
   timeout := make(chan int)
   go func() {
      time.Sleep(time.Second)
      timeout <- 1
    }()

    res := make(chan int)
    go func() {
        for {
        }
        res <- 1
    }()
    select {
        case <-timeout:
            fmt.Println("timeout")
        case <-res:
            fmt.Println("res")
    }
}

Au lieu de se terminer après un Deuxièmement, le programme entre dans une boucle infinie. Pourquoi cela se produit-il ?

Comprendre la planification coopérative dans Go

La réponse réside dans l'utilisation par Go de la planification coopérative pour les goroutines. Les Goroutines cèdent le contrôle au planificateur dans certaines conditions, notamment :

  • Opérations d'envoi/réception de canal sans tampon
  • Appels système (par exemple, E/S fichier/réseau)
  • Allocation de mémoire
  • time.Sleep() appels
  • runtime.Gosched() appels

Étant donné que la boucle infinie de la première goroutine ne cède jamais, elle empêche les autres goroutines de s'exécuter et d'envoyer des messages aux canaux. Cela inclut le canal de délai d'attente, qui attend un message qui n'arrivera jamais.

Solutions potentielles

Bien que la planification coopérative puisse conduire à de telles situations, il existe des solutions potentielles :

  • Augmentation de GOMAXPROCS : Cette variable d'environnement permet à plusieurs threads de exécuter des goroutines simultanément, réduisant ainsi la probabilité qu'une goroutine en bloque d'autres.
  • Utilisation d'un planificateur préemptif (objectif futur) : Les développeurs du langage Go visent à implémenter un planificateur préemptif, qui basculerait de force entre les goroutines , éliminant le problème du blocage.
  • Rendement manuel :Le La fonction runtime.Gosched() permet aux goroutines de céder manuellement le contrôle au planificateur, éliminant ainsi les boucles infinies qui pourraient en bloquer d'autres.

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