fő csomag import ( "fmt" ) func main() { c := make(chan string) go fmt.Println(<-c) c <- "Helló Világ!" fmt.Println("Kimenet!") } fatális hiba: minden goroutine alvó állapotban van - deadlock! goroutine 1 [csatorna fogadása]: main.main() /tmp/sandbox[phone]/prog.go:10 +0x3a A program kilépett: státusz 2.
sobes.tech MI
Válasz az MI-től
A fatal error: all goroutines are asleep - deadlock! hiba akkor fordul elő, amikor minden goroutine blokkolva van, és egyik sem tud tovább lépni.
Ebben a kódban:
c := make(chan string)
go fmt.Println(<-c)
c <- "Hello World!"
fmt.Println("Exit!")
A c csatorna puffer nélküli, így az küldési (c <-) és fogadási (<-c) műveleteknek egy időben kell megtörténniük.
Magyarázat:
- A
go fmt.Println(<-c)goroutine megpróbál értéket fogadni accsatornáról. - A fő goroutine megpróbálja elküldeni a
"Hello World!"értéket accsatornára.
Azonban, mivel a fmt.Println(<-c) külön goroutine-ban fut, és a küldés a fő goroutine-ban történik, előfordulhat, hogy a fogadó goroutine még nem készült az adatok fogadására, és a fő goroutine blokkol a küldésnél.
Ennek eredményeként mindkét goroutine blokkol: az egyik vár a küldésre, a másik a fogadásra, de egyik sem tud tovább lépni — deadlock keletkezik.
A probléma megoldására:
- Bufferelt csatornát lehet használni, például
c := make(chan string, 1), így a küldés nem blokkol. - Vagy meg lehet változtatni a műveletek sorrendjét, először küldeni, majd olvasni.
Bufferelt példával:
c := make(chan string, 1)
go fmt.Println(<-c)
c <- "Hello World!"
fmt.Println("Exit!")
Most a program deadlock nélkül fog futni.