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 } }
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!