Goroutine ile çalışırken deadlock nedir?
sobes.tech yapay zeka
AI'dan gelen yanıt
Deadlock (ölü nokta), iki veya daha fazla goroutine'un birbirini bekleyerek kilitlendiği ve hiç birinin çalışmaya devam edemediği bir durumdur. En sık mutexler veya kanallar kullanılırken ortaya çıkar.
Deadlock örnekleri:
-
Farklı sırayla mutex kilitleme:
// Mutexlerle deadlock örneği var mu1 sync.Mutex var mu2 sync.Mutex func goroutine1() { mu1.Lock() // mu1 kilitleniyor time.Sleep(100 * time.Millisecond) // Biraz bekliyor mu2.Lock() // mu2'yi kilitlemeye çalışıyor (goroutine2 tarafından tutuluyor) fmt.Println("goroutine1 mu2'yi edindi") mu2.Unlock() mu1.Unlock() } func goroutine2() { mu2.Lock() // mu2'yi kilitliyor time.Sleep(100 * time.Millisecond) // Biraz bekliyor mu1.Lock() // mu1'yi kilitlemeye çalışıyor (goroutine1 tarafından tutuluyor) fmt.Println("goroutine2 mu1'i edindi") mu1.Unlock() mu2.Unlock() }Goroutine1 mu1'i kilitledi ve mu2'yi bekliyor. Goroutine2 mu2'yi kilitledi ve mu1'i bekliyor. Her ikisi de kilitli durumda.
-
Tüketici olmadan buffer olmayan kanala gönderim:
// Deadlock örneği kanal ile func main() { ch := make(chan int) //go func() { // Okuma yapan bir goroutine başlatılmazsa deadlock olur // <-ch //}() ch <- 1 // Aktif bir alıcı olmadan kanala gönderim fmt.Println("Kanal'a gönderildi") // Bu satıra ulaşılmaz }Buffer olmayan kanala gönderim, başka bir goroutine'den okuma başlamadan engellenir. Alıcı yoksa deadlock oluşur.
-
Kapanmış veya boş buffer'lı kanaldan okuma:
// Kapanmış kanaldan okuma sırasında deadlock func main() { ch := make(chan int, 1) // 1 elemanlı bufferli kanal ch <- 1 // Gönderildi close(ch) // Kanal kapatıldı <-ch // 1 okundu <-ch // Kapanmış ve boş kanaldan tekrar okuma - deadlock }Kapanmış ve boş olmayan kanaldan okuma başarılı olur. Kapanmış ve boş kanal veya açık ama boş kanal okuma blokajına neden olur.
Golang çalışma zamanı belirli deadlock türlerini tespit edebilir (örneğin, tüm kilitli goroutine'ler tek bir goroutine'den alma veya gönderme bekliyorsa), ve bu durumda program "fatal error: all goroutines are asleep - deadlock!" mesajıyla aniden sona erer. Ancak, tüm deadlock'lar otomatik olarak tespit edilemeyebilir.
Deadlock'u önlemek için:
- Mutexleri tutarken tutarlı bir sıralama izlemek.
- Buffer olmayan kanala her gönderim için uygun bir okuma olduğunu sağlamak ve tersi.
- Gerekirse
selectkullanmak vedefaultveya zaman aşımı eklemek. - Goroutine'lerin yaşam süresini ve kanalların kapanmasını dikkatli yönetmek.