Soru tarihçesi:
Go dili, zaman yönetimi için temel işlevler olan time.Sleep ve time.After ile time paketini ilk gününden itibaren sağlamıştır. Sistem uykusu (System.sleep) olan dillerin aksine, Go, kendi primitifleri aracılığıyla asenkron zamanlayıcıları uygular, bu çoklu iş parçacığı çalışması için önemlidir.
Sorun:
Geliştiriciler sıklıkla görevler arasında beklemeler uygulamak için time.Sleep'i yanlış kullanır, bu da rekabetçi programlarda istenmeyen sonuçlar doğurur. Go paradigmasında, olayların beklenmesi yönetimini kanallar ve select/time.After ile kurmak daha doğrudur.
Çözüm:
time.Sleep(d) geçerli iş parçacığını d süre boyunca bloke eder, bu doğrudan bir "uyku"dur. time.After(d) bir kanalı döndürür, bu kanalda d süresi içinde bir olay zamanlanır. Son seçim, select ile kanallarda çok daha esnektir, kesintiye uğratılabilir beklemeler ve zaman aşımı için uygundur.
Kod örneği:
ch := make(chan struct{}) go func() { time.Sleep(2 * time.Second) ch <- struct{}{} }() select { case <-ch: fmt.Println("tamam") case <-time.After(1 * time.Second): fmt.Println("zaman aşımı") }
Anahtar özellikler:
time.Sleep'i tüm programın çalışmasını bloke etmek için kullanabilir miyiz?
Hayır, time.Sleep yalnızca tek bir iş parçacığını "uykuya" dalmasına neden olur, diğerleri çalışmaya devam eder.
time.After bellek sızıntısına neden olabilir mi, eğer kanal okunmazsa?
Evet, zamanlayıcı, değer okunana kadar askıda kalır; okumazsanız, çöp toplayıcı nesneyi silmez.
Kod örneği:
func leak() { for { _ = time.After(time.Hour) } }
time.After ile olay alınmadığında beklemeyi nasıl doğru bir şekilde iptal ederiz?
Bir zamanlayıcı oluşturmak ve eğer süre dolmadan beklemeyi sonlandırmanız gerekiyorsa, manuel olarak durdurmak daha iyidir:
t := time.NewTimer(time.Minute) if done { t.Stop() }
Bir iş parçacığı bir sinyal bekliyor ve zaman aşımı durumunda şöyle yapıyor:
time.Sleep(10*time.Second) doSomething()
Artıları:
Eksileri:
Kod, select ve time.After ile oluşturulur:
select { case <-workSignal: // Uygulamak case <-time.After(10 * time.Second): // Zaman aşımında yapmak }
Artıları:
Eksileri: