Maison > développement back-end > Golang > Comment un Goroutine avec une boucle infinie peut-il bloquer d'autres Goroutines en Go ?

Comment un Goroutine avec une boucle infinie peut-il bloquer d'autres Goroutines en Go ?

DDD
Libérer: 2024-12-04 22:33:14
original
855 Les gens l'ont consulté

How Can a Goroutine with an Infinite Loop Block Other Goroutines in Go?

Goroutines bloquant les autres

Dans Go, une goroutine est un fil d'exécution léger. Normalement, les goroutines peuvent s'exécuter simultanément sans se bloquer. Cependant, dans certaines circonstances, une goroutine peut bloquer l'exécution des autres.

Considérez le code suivant :

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")
    }
}
Copier après la connexion

Dans cet exemple, une goroutine est démarrée avec une boucle infinie. Normalement, cette goroutine ne devrait pas empêcher les autres goroutines de s'exécuter. Cependant, il semble que la première goroutine empêche la deuxième goroutine d'envoyer vers le canal de délai d'attente.

Explication

Ce comportement est dû à la façon dont les goroutines sont programmé dans Go. La planification coopérative est utilisée, ce qui signifie que les goroutines doivent volontairement céder l'exécution au planificateur pour qu'une autre goroutine puisse s'exécuter. Dans le code fourni, la goroutine avec la boucle infinie ne cède jamais, ce qui empêche l'autre goroutine de progresser.

Les goroutines cèdent généralement dans les conditions suivantes :

  • Envoi de canal sans tampon /receive
  • Appels système (par exemple, fichier/réseau lectures/écritures)
  • Allocation de mémoire
  • Time.Sleep() est appelée
  • runtime.Gosched() est appelée

Dans ce cas , aucune de ces conditions n'est remplie, donc la goroutine avec la boucle infinie continue de fonctionner indéfiniment.

Solutions

Pour résoudre ce problème, il existe plusieurs solutions possibles :

  • Utilisez un planificateur préemptif. Il s'agit d'un travail en cours, mais cela permettrait d'interrompre les goroutines à tout moment, qu'elles soient ou non. cédant.
  • Utilisez des canaux sans tampon. Lors de l'envoi vers un canal sans tampon, l'expéditeur bloquera jusqu'à ce qu'un autre goroutine soit prêt à recevoir.
  • Utilisez une minuterie. La fonction time.After() peut être utilisée pour créer un canal qui recevra après une durée spécifiée. En envoyant sur ce canal, vous pouvez forcer la goroutine à céder.
  • Utilisez runtime.Gosched() dans la boucle infinie. Cela cédera explicitement l'exécution au planificateur.

La meilleure solution pour votre application spécifique dépendra de la nature des goroutines et du comportement souhaité.

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!

source:php.cn
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