Heim >Backend-Entwicklung >Golang >Warum bleibt eine Go Select-Anweisung mit einer Goroutine hängen, es sei denn, eine Print-Anweisung wird hinzugefügt?

Warum bleibt eine Go Select-Anweisung mit einer Goroutine hängen, es sei denn, eine Print-Anweisung wird hinzugefügt?

Linda Hamilton
Linda HamiltonOriginal
2024-11-26 22:46:11445Durchsuche

Why Does a Go Select Statement with a Goroutine Hang Unless a Print Statement is Added?

Goroutine mit Select stoppt nicht, es sei denn, eine Print-Anweisung wird hinzugefügt

In der Go-Tour-Übung Nr. 71 wird Select ohne Standard verwendet -Anweisung kann zu einer Endlosschleife führen, die verhindert, dass die Goroutine beendet wird. Dieses Problem tritt auf, wenn 71_hang.go mit dem Argument „nogood“, aber nicht mit dem Argument „ok“ ausgeführt wird.

Der Unterschied zwischen den beiden Szenarios besteht im Vorhandensein einer zusätzlichen fmt.Print("")-Anweisung in der Standardeinstellung Fall der SELECT-Anweisung. Standardmäßig werden Blöcke ausgewählt, bis einer der Kanäle eine Nachricht zum Empfangen hat. Im Standardfall führt select jedoch die Standardanweisung aus, auch wenn auf keinem der Kanäle Nachrichten verfügbar sind.

Im Originalcode, ohne die fmt.Print("")-Anweisung, wurde in der select-Anweisung eine eingegeben Endlosschleife, da keine Kanäle mit Nachrichten verfügbar waren und im Standardfall nichts unternommen wurde, um der Goroutine die Planung zu ermöglichen. Durch das Hinzufügen der fmt.Print("")-Anweisung konnte der Scheduler andere Goroutinen planen und die Endlosschleife unterbrechen.

Alternativ kann der Code so geändert werden, dass er select auf nicht blockierende Weise verwendet und die anderen Goroutinen zulässt richtig laufen zu lassen. Dies kann erreicht werden, indem die Standardanweisung entfernt und eine separate if-Anweisung verwendet wird, um zu prüfen, ob der Crawling-Zähler Null erreicht hat, wie im geänderten Code unten gezeigt:

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

Das obige ist der detaillierte Inhalt vonWarum bleibt eine Go Select-Anweisung mit einer Goroutine hängen, es sei denn, eine Print-Anweisung wird hinzugefügt?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn