Evet, karmaşık ama işleri daha kolay hale getirecek birkaç temel kural var.
- Global kapsamdaki kanallara erişmek yerine, rutinlere ilettiğiniz kanallar için resmi argümanlar kullanmayı tercih edin . Bu şekilde daha fazla derleyici denetimi ve daha iyi modülerlik elde edebilirsiniz.
- aynı kanalda ('ana' olan dahil) hem okumaktan hem de yazmaktan kaçının . Aksi takdirde, kilitlenme çok daha büyük bir risktir.
İşte programınızın bu iki yönergeyi uygulayan alternatif bir sürümü. Bu vaka, bir kanaldaki birçok yazarı ve bir okuyucuyu göstermektedir:
c := make(chan string)
for i := 1; i <= 5; i++ {
go func(i int, co chan<- string) {
for j := 1; j <= 5; j++ {
co <- fmt.Sprintf("hi from %d.%d", i, j)
}
}(i, c)
}
for i := 1; i <= 25; i++ {
fmt.Println(<-c)
}
http://play.golang.org/p/quQn7xePLw
Her biri beş kez yazan tek bir kanala yazan beş go-rutini oluşturur. Ana go-rutini yirmi beş mesajın hepsini okur - göründükleri sıranın genellikle sıralı olmadığını fark edebilirsiniz (yani eşzamanlılık açıktır).
Bu örnek, Go kanallarının bir özelliğini göstermektedir: bir kanalı paylaşan birden çok yazarın olması mümkündür; Git, mesajları otomatik olarak araya ekleyecektir.
Aynısı, buradaki ikinci örnekte görüldüğü gibi, bir kanaldaki bir yazar ve birden fazla okuyucu için de geçerlidir:
c := make(chan int)
var w sync.WaitGroup
w.Add(5)
for i := 1; i <= 5; i++ {
go func(i int, ci <-chan int) {
j := 1
for v := range ci {
time.Sleep(time.Millisecond)
fmt.Printf("%d.%d got %d\n", i, j, v)
j += 1
}
w.Done()
}(i, c)
}
for i := 1; i <= 25; i++ {
c <- i
}
close(c)
w.Wait()
Bu ikinci örnek , ana gorutine uygulanan ve diğer beş gorutinin erken sonlandırılmasına neden olan ( bu düzeltme için olov sayesinde) bir beklemeyi içerir .
Her iki örnekte de arabelleğe almaya gerek yoktu. Arabelleğe almayı yalnızca bir performans artırıcı olarak görmek genellikle iyi bir ilkedir. Programınız tamponlar olmadan kilitlenmezse , tamponlarla da kilitlenmez (ancak tersi her zaman doğru değildir ). Bu nedenle, başka bir pratik kural olarak, arabelleğe almadan başlayın ve daha sonra gerektiği gibi ekleyin .
original, hi from 4
...