հիմնական փաթեթ միավոր ( "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-ի։