Sobes.tech
Senior

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 a c csatornáról.
  • A fő goroutine megpróbálja elküldeni a "Hello World!" értéket a c csatorná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.