goroute mit select wird ohne fmt.Print() nicht beendet
In der Go-Tour-Übung Nr. 71 ein Goroute mit einer select-Anweisung wird kontinuierlich ausgeführt, es sei denn, im Standardfall wird eine fmt.Print()-Anweisung hinzugefügt. Dieses Verhalten entsteht aufgrund der geänderten Operation von select, wenn eine Standardanweisung vorhanden ist.
Ohne eine Standardanweisung blockiert select, bis eine Nachricht auf einem der überwachten Kanäle empfangen wird. Durch Hinzufügen eines Standardwerts führt select den Standardzweig immer dann aus, wenn keiner der Kanäle Nachrichten enthält.
Im Originalcode erstellt die Standardanweisung eine Endlosschleife:
for { select { case todo := <-toDoList: ... case <-doneCrawling: ... default: if os.Args[1] == "ok" { fmt.Print("") } if crawling == 0 { goto END } } }
Ohne die fmt. Wenn Print() standardmäßig verwendet wird, kann der Scheduler keine anderen Goroutinen planen, was zu einem Deadlock führt. Durch das Hinzufügen von fmt.Print() kann der Scheduler seine normale Funktion fortsetzen und so den Abschluss der Goroutine ermöglichen.
Eine Änderung des Codes zur Verwendung einer nicht blockierenden Auswahl behebt das Problem:
for { select { case todo := <-toDoList: ... case <-doneCrawling: ... } if crawling == 0 { break } }
Alternativ kann der Originalcode durch Setzen von GOMAXPROCS=2 zum Laufen gebracht werden, was auf ein Problem mit einem überlasteten Scheduler hinweist.
Das obige ist der detaillierte Inhalt vonWarum benötigt eine Go-Anweisung „select' „fmt.Print()', um in einer bestimmten Goroutine zu enden?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!