Case Study: The Goroutine That Never Finishes
Amaliy holat: hech qachon tugamaydigan goroutine
Ikki odamni tasavvur qiling: ular telefon orqali gaplashishga kelishgan, lekin ikkalasi ham "sen birinchi qo'ng'iroq qil" deb, IKKALASI ham kutib turibdi — hech biri birinchi bo'lib qo'ng'iroq qilmaydi. Ular ABADIY shu holatda qolishlari mumkin, chunki har biri boshqasining harakatini kutmoqda. Bu — dasturlashdagi deadlock yoki "hech qachon tugamaydigan kutish"ning aniq tasviri.
Stsenariy: sizning dasturingiz ba'zan "osilib qoladi" — hech qanday xato bermaydi, lekin ham hech narsa qilmaydi, dastur to'xtab qoladi. go tool pprof yoki oddiy kuzatuv orqali, siz goroutine'lar soni VAQT O'TISHI bilan doimiy o'sib borayotganini ko'rasiz — ular ochiladi, lekin hech qachon yopilmaydi.
func processInBackground(jobs <-chan Job) {
results := make(chan Result) // buferlanmagan kanal
for job := range jobs {
go func(j Job) {
result := doWork(j)
results <- result // bu yerda hech kim tinglamasa, abadiy kutadi
}(job)
}
}Concurrency Fundamentals kursida ko'rgan buferlanmagan (unbuffered) kanal — yuboruvchi va qabul qiluvchi BIR VAQTDA "tayyor" bo'lishini talab qiladi. Bu kodda har bir job uchun yangi goroutine ishga tushiriladi, u ishni bajarib, natijani results kanaliga yubormoqchi bo'ladi — LEKIN hech kim results kanalidan O'QIMAYDI. Har bir goroutine results <- result qatorida ABADIY kutib qoladi.
- •Guessing vs Forming a Hypothesis darsidagi kabi gipoteza: "agar goroutine'lar soni cheksiz o'ssa va hech qachon kamaymasa, demak ular biror joyda BLOKLANIB qolyapti, hech qachon tugamayapti"
- •Har bir yangi
job— yangi goroutine yaratadi, lekinprocessInBackgroundfunksiyasi natijalarni HECH QACHON o'qimaydi — kanal faqat yozish uchun ishlatiladi, o'qish uchun emas - •Reading a Stack Trace darsidagi kabi: dastur "osilib qolganda" Go'ning
SIGQUITsignali (yoki debugger) orqali BARCHA goroutine'larning stack trace'ini olsa, ko'plab goroutine aynan shuresults <- resultqatorida to'xtab qolganini ko'rasiz
Sabab topildi: results kanaliga yozilgan qiymatlarni hech kim o'qimaydi, shuning uchun har bir yozuvchi goroutine ABADIY bloklanib qoladi — hech qachon tugamaydi, hech qachon xotiradan chiqmaydi. Yechim — yo natijalarni o'qiydigan alohida "yig'uvchi" goroutine qo'shish, yo results kanalini butunlay olib tashlab, agar natija darhol kerak bo'lmasa.
Umumiy saboq: hech qachon tugamaydigan goroutine deyarli har doim kanalga yozish yoki o'qishning "boshqa tomoni yo'q" holatini ko'rsatadi. Bunday xatoni qidirishda: "bu kanalga har doim kimdir tinglayaptimi?" va "bu goroutine tugashi uchun aynan qanday shart bajarilishi kerak?" degan ikkita savolni bering.
Key Takeaway
Key Takeaway:
Hech qachon tugamaydigan goroutine — odatda kanalga yozish yoki o'qishning "boshqa tomoni" yo'qligini bildiradi: goroutine abadiy kutadi, chunki hech kim uning xabarini qabul qilmaydi. Har bir yaratilgan goroutine uchun "u aniq qachon va qanday tugaydi" savolini bering.
NEXT UP
Writing Up the Root Cause