Der PHP-Editor Xiaoxin ist hier, um Ihnen einen häufigen Deadlock bei gleichzeitigen Programmierproblemen vorzustellen. Deadlock bedeutet, dass alle Goroutinen in den Ruhezustand übergegangen sind und nicht weiter ausgeführt werden können, selbst wenn Mechanismen wie Wartegruppen verwendet werden. In diesem Fall können nicht alle Goroutinen vorwärts gehen, was dazu führt, dass das Programm in einen unendlichen Wartezustand fällt. Bei der gleichzeitigen Programmierung ist es sehr wichtig, Deadlocks zu vermeiden, und wir müssen seine Ursachen und Lösungen verstehen, um den normalen Betrieb des Programms sicherzustellen.
Ich lerne Go-Parallelität und möchte, dass zwei Go-Routinen weiterhin miteinander kommunizieren und gleichzeitig aktualisierte Werte über einen Kanal weitergeben. Einer addiert 2 und der andere subtrahiert 1. Der Code und die Ausgabe lauten wie folgt:
Was stimmt mit diesem Code nicht?
package main import ( "fmt" "sync" "time" ) var wg sync.waitgroup func addtwo(r chan int, e chan int) { val := <-r fmt.println("at recieved: ", val) time.sleep(1 * time.second) e <- val + 2 } func subtractone(r chan int, e chan int) { val := <-r fmt.println("so recieved: ", val) time.sleep(1 * time.second) e <- val - 1 } func main() { ch := make(chan int) ch2 := make(chan int) wg.add(1) go addtwo(ch, ch2) wg.add(1) go subtractone(ch2, ch) ch <- 1 wg.wait() }
Ausgabe:
AT Recieved: 1 SO Recieved: 3 fatal error: all goroutines are asleep - deadlock! goroutine 1 [semacquire]: sync.runtime_Semacquire(0x4b2de8?) /usr/lib/go-1.18/src/runtime/sema.go:56 +0x25 sync.(*WaitGroup).Wait(0x0?) /usr/lib/go-1.18/src/sync/waitgroup.go:136 +0x52 main.main()
Dann hört es auf.
Warum tauscht die Goroutine nicht immer Werte aus, auch wenn ich wg.done() in der Goroutine nicht aufrufe?
Beide Goroutinen, die Sie starten, empfangen einfach einen Wert, senden einen Wert und enden dann. Von da an ist es nur noch main
goroutine,在 wg.wait()
处被阻止,因为你从未调用 wg.done()
.
Sie haben vergessen, eine (n Endlos-)Schleife zu verwenden:
func addtwo(r chan int, e chan int) { for { val := <-r fmt.println("at recieved: ", val) time.sleep(1 * time.second) e <- val + 2 } } func subtractone(r chan int, e chan int) { for { val := <-r fmt.println("so recieved: ", val) time.sleep(1 * time.second) e <- val - 1 } }
Mit dieser Änderung läuft Ihre Anwendung für immer und die Ausgabe lautet:
AT Recieved: 1 SO Recieved: 3 AT Recieved: 2 SO Recieved: 4 AT Recieved: 3 SO Recieved: 5 AT Recieved: 4 ....
Das obige ist der detaillierte Inhalt vonDeadlock – alle Goroutinen schlafen (sogar bei Verwendung von Wartegruppen). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!