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!")

ახლა პროგრამა მუშაობს ბლოკირების გარეშე.