Heim  >  Artikel  >  Backend-Entwicklung  >  Warum wird in diesem Fall die Haupt-Coroutine blockiert, was zu einem Deadlock führt?

Warum wird in diesem Fall die Haupt-Coroutine blockiert, was zu einem Deadlock führt?

PHPz
PHPznach vorne
2024-02-09 15:42:09604Durchsuche

Warum wird in diesem Fall die Haupt-Coroutine blockiert, was zu einem Deadlock führt?

In PHP kommt es häufig vor, dass die Haupt-Coroutine blockiert wird, was zu einem Deadlock führt. Wenn die Haupt-Coroutine während der Ausführung auf blockierende Vorgänge wie Netzwerkanforderungen, E/A-Vorgänge oder das Warten auf die Ergebnisse anderer Coroutinen stößt und keine geeignete Verarbeitungsmethode vorhanden ist, kann es zu einem Deadlock kommen. In diesem Fall kann die Haupt-Coroutine nicht weiter ausgeführt werden, und andere Coroutinen erhalten keine Gelegenheit zur Ausführung, und das gesamte Programm gerät in einen Deadlock. Warum wird in diesem Fall die Haupt-Coroutine blockiert, was zu einem Deadlock führt? Lassen Sie uns dies unten beantworten.

Frageninhalt

package main

import "fmt"

func square(numbers chan int, squares chan int) {
    for n := range numbers {
        squares <- n * n
    }
    close(squares)
}

func main() {
    numbers := make(chan int)
    squares := make(chan int)

    go square(numbers, squares)

    for i := 0; i < 10; i++ {
        numbers <- i
    }
    close(numbers)

    for s := range squares {
        fmt.Println(s)
    }
}

Ich meine, ich weiß, dass die Nummer in einer separaten Goroutine an den numbers-Kanal gesendet werden muss, damit dieser Code funktioniert, wie zum Beispiel:

go func() {
for i := 0; i < 10; i++ {
    numbers <- i
}

}

Trotzdem fällt es mir schwer zu erklären, warum der Deadlock auftritt. Mir ist durchaus bewusst, dass der Scheduler keine Ausführungsreihenfolge garantiert. Stimmt es jedoch nicht, dass beim ersten Senden an den numbers 通道时,主 goroutine 被阻塞,但随后调度程序可能会开始执行 square-Kanal in der Schleife die Haupt-Goroutine blockiert wird, der Scheduler dann jedoch möglicherweise mit der Ausführung der Goroutine square beginnt und sie dann hin und her kommunizieren? her?

Workaround

Der Grund, warum die Haupt-Goroutine blockiert ist, liegt darin, dass Sie in diesem Fall nach dem Senden der Daten an den Quadratkanal keinen Wert aus dem Quadratkanal lesen.

Wenn Sie numbers 时,你的 <code>go square ausführen, empfängt die Goroutine den Wert und sendet ihn an den Quadratkanal. Gleichzeitig empfängt Ihre Haupt-Goroutine jedoch keine Werte vom Square-Kanal, da Ihre Haupt-Goroutine immer noch Daten an den Numbers-Kanal sendet.

Das bedeutet, dass Ihre Haupt-Coroutine diese Zeile niemals ausführt for s := range squares und es dann zu einem Deadlock kommt.

Um diesen Code korrekt auszuführen, können Sie ihn wie unten gezeigt ändern.

package main

import "fmt"

func square(numbers chan int, squares chan int) {
    for n := range numbers {
        squares <- n * n
    }
    close(squares)

}

func main() {
    numbers := make(chan int)
    squares := make(chan int)

    go square(numbers, squares)

    go func() {
        for i := 0; i < 10; i++ {
            numbers <- i
        }
        close(numbers)
    }()

    for s := range squares {
        fmt.Println(s)
    }
}

Das obige ist der detaillierte Inhalt vonWarum wird in diesem Fall die Haupt-Coroutine blockiert, was zu einem Deadlock führt?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen