Sobes.tech
Senior

հիմնական փաթեթ միավոր ( "fmt" ) գործառույթ main() { c := make(chan string) go fmt.Println(<-c) c <- "Բարեւ աշխարհ!" fmt.Println("Ելք!") } վտանգավոր սխալ: բոլոր goroutine-ները քնած են - deadlock! goroutine 1 [կանալի ընդունում]: main.main() /tmp/sandbox[phone]/prog.go:10 +0x3a Ծրագիրը դուրս եկավ: վիճակ 2.

sobes.tech AI

Պատասխան AI-ից

fatal error: all goroutines are asleep - deadlock! սխալը տեղի է ունենում, երբ բոլոր goroutine-ները փակված են և ոչ մեկը չի կարող շարունակել:

Այս կոդում՝

c := make(chan string)
go fmt.Println(<-c)
c <- "Hello World!"
fmt.Println("Exit!")

Կանալ c ստեղծվում է առանց բուֆեր, հետևաբար, ուղարկման (c <-) և ստացման (<-c) գործողությունները պետք է տեղի ունենան միաժամանակ:

Ներմուծում՝

  • Goroutine go fmt.Println(<-c) փորձում է ստանալ արժեքը c-ից:
  • Գլխավոր goroutine փորձում է ուղարկել արժեքը "Hello World!"c-ին:

Բայց, քանի որ fmt.Println(<-c) աշխատում է առանձին goroutine-ում, իսկ ուղարկումը կատարվում է գլխավոր goroutine-ում, հնարավոր է, որ ընթերցող goroutine-ը դեռ պատրաստ չէ ընդունել տվյալները, և գլխավոր goroutine-ը բլոկվում է ուղարկման վրա:

Արդյունքում՝ երկու goroutine-ները բլոկվում են՝ մեկը սպասում է ուղարկմանը, մյուսը՝ ընդունմանը, բայց ոչ մեկը չի կարող շարունակել՝ առաջանում է deadlock:

Որպես լուծում՝ կարող եք:

  • Կանալը դարձնել բուֆերային, օրինակ՝ c := make(chan string, 1), որպեսզի ուղարկումը չբլոկվի:
  • կամ փոխել գործողությունների կարգը՝ սկզբում ուղարկել, հետո կարդալ:

Բուֆերային օրինակ՝

c := make(chan string, 1)
go fmt.Println(<-c)
c <- "Hello World!"
fmt.Println("Exit!")

Այժմ ծրագիրը կաշխատի առանց deadlock-ի։