Maison > développement back-end > Golang > Pourquoi une instruction Go « select » se bloque-t-elle sans cas « par défaut » et comment peut-elle être corrigée ?

Pourquoi une instruction Go « select » se bloque-t-elle sans cas « par défaut » et comment peut-elle être corrigée ?

Barbara Streisand
Libérer: 2024-11-24 06:31:15
original
349 Les gens l'ont consulté

Why Does a Go `select` Statement Hang Without a `default` Case and How Can It Be Fixed?

Goroutine avec Select ne s'arrête pas sans fmt.Print()

Problème :

Dans l'exercice Go Tour # 71, en utilisant go run 71_hang.go nogood, le programme s'exécute indéfiniment, tandis que go run 71_hang.go ok fonctionne comme prévu. La seule différence est l'ajout de fmt.Print("") dans le cas par défaut de l'instruction select.

Explication :

Une instruction par défaut dans une sélection change le comportement de la déclaration. Sans valeur par défaut, sélectionnez les blocs jusqu'à ce qu'il y ait des messages sur les canaux. Avec une valeur par défaut, select exécute l'instruction par défaut chaque fois qu'il n'y a rien à lire sur les canaux.

Dans le code original, l'instruction par défaut crée une boucle infinie. Étant donné que le planificateur ne peut pas programmer d'autres goroutines, le programme s'exécute indéfiniment.

Solution 1 :

Supprimez l'instruction par défaut et utilisez une sélection non bloquante :

for {
    select {
        case todo := <-toDoList:
            if todo.depth > 0 && !visited[todo.url] {
                crawling++
                visited[todo.url] = true
                go crawl(todo, fetcher, toDoList, doneCrawling)
            }
        case <-doneCrawling:
            crawling--
    }
    if crawling == 0 {
        break
    }
}
Copier après la connexion

Solution 2 :

Conserver l'instruction par défaut mais assurez-vous que la goroutine cède. Une façon d'y parvenir consiste à utiliser GOMAXPROCS=2, qui permet au planificateur d'utiliser plusieurs cœurs.

Remarque supplémentaire :

Les goroutines sont planifiées de manière coopérative. Select est un point où une goroutine devrait céder. Cependant, dans l'exemple donné, la raison pour laquelle select ne donne pas sans l'instruction fmt.Print() n'est pas entièrement comprise et nécessite une enquête plus approfondie.

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
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal