Concurrent Programming with Go — 3

Hande Ebrar Gunesdogdu
3 min readDec 29, 2022

Bir önceki yazıda, task’ların senkronizasyonunu sağlayabilmek için sync package, shared memory konusu için mutex kavramlarına değindik. Serinin bu yazısında ise, birden fazla Goroutine arasındaki çalışmayı koordine etmeyi sağlayan channel’lardan bahsedeceğiz.

Channels

Channel’ların çalışma mantığını Rob Pike’ın şu cümlesiyle özetleyebiliriz:

Don’t communicate by sharing memory; share memory by communicating.

Uygulamalarımız genişledikçe, birden fazla concurrent task arasında paylaşıldığında belleği yönetmek çok zor olabilir. Shared memory’deki read/write işlemleri için mutex kullanabiliriz fakat ve uygulamanın tamamına yayılmış olan birden çok Goroutine arasında paylaşıldığı için zamanla yönetimi zorlaşabilir. Bunun yerine channel’ları kullanabiliriz.

Mutex, belleğin belirli bir kısmını korur ve sadece bir işlem belleği manipüle edebilir. Channel ise belleğin bir kopyalarını oluşturur ve uygulamaya bunu iletir. Channel’ın bir tarafında mesajı gönderecek olan bir gönderen Goroutine(sender), diğer tarafta da mesajı alan başka bir Goroutine(receiver) bulunur. Burada alınan mesaj, orijinal mesajın kendisi değil, kopyası olacaktır. Dolayısıyla Goroutine’ın lock, unlock gibi yapıları bilmesine ve kontrol etmesine gerek kalmaz.

Channel oluşturmak için Go’daki built-in function’lardan make() kullanılır. Bu fonksiyona, channel ile gönderilecek ve alınacak mesajın tipinin parametre olarak belirtilmesi gerekir.

Channel’lar sayesinde Goroutine’ler birbirleriyle ilgili bir şey bilmek durumunda kalmaz. Aşağıdaki kod parçasında 13. satırda bulunan goroutine sadece channel içerisine 42 numarasının gönderildiğini bilir. Receiver tarafta bulunan, 8. satırdaki goroutine channel’dan bir tamsayı alacağını bilir, ancak bunun nereden geldiğiyle ilgilenmez. Yani bu iki goroutine birbirinden tamamen ayrılmıştır. Sahip oldukları tek bağımlılık, goroutine’ler arasındaki koordinasyonu sağlayan channel’dır.

Channel Types

Channel default olarak, mesajı gönderen ve gönderilen mesajı alan bidirectional channel type’ında oluşturulurlar. Ancak ihtiyaca göre farklı channel type’lar da seçilebilinir. Send-only sadece mesaj gönderen, receive-only sadece gönderilen mesajı alan channel type’lardır.

Closing Channels

Uygulamamızda, bir süre sonra channel içerisinden göndereceğimiz mesaj kalmayabilir. Bu durumda receiver’a daha fazla mesaj gelmeyeceğini bildirmek için bu channel’ı kapatmamız gerekir. Burada dikkat etmemiz gereken bir konu ise kapatılan channel’ların tekrar kullanımında problem yaşanacağıdır.

Bir channel’ı kapattıktan sonra tekrar mesaj göndermeyi denersek uygulama panic fırlatır.😱 Kapalı olan bir channel’dan mesaj almayı denersek default değer döner.

Bu gibi durumlarda kullanılan channel’ın kapalı olup olmadığını anlamak için uygulamamızda control-flow’lardan faydalanabiliriz. Channel’ın açık olup olmadığını ok parametresiyle kontrol edip, sadece açık olduğu durumlarda mesaj send/receive yapılır.

Select Statements

Go’da sadece channel’lara özel bir control-flow olarak bulunun select statements, switch-case yapısına benzer. Switch-case’deki gibi bir koşula karşı doğruluğu kontrol etmek yerine, bir channel’dan mesaj göndermeyi veya almayı deneriz.

İlk case, ch1'den → i değişkenine mesaj almayı deniyor. Diğer case ise ch’ye “hello” metnini göndermeyi deniyor. Uygulamada o anda alınmayı bekleyen bir mesaj varsa ilk case’e, gönderilmeyi bekleyen mesaj varsa ikinci case’e girecek. İki durum da aynı anda gerçekleşirse rastgele olarak case seçilir ve çalışır. Switch-case’deki gibi önceden belirlenmiş bir sıra yoktur.

Select deyimi bir case‘i gerçekleştirirken diğer tüm case’lerin çalışmasını bloklar. ch1'den mesaj alana kadar ya da ch2'den mesaj gönderene kadar goroutine burada duracaktır. Buna blocking select statement denir. default keyword kullanarak bu bloklama kaldırılabilinir (non-blocking select).

Bu seride(1 , 2) Go’da concurrent programlamaya ayrıntılarıyla değinmeye çalıştım. Okuyan ve destek olan herkese teşekkür ederim. Faydalı olması dileğiyle! 🌟

References and Links

⭐ Concurrency in Go, Katherine Cox-Buday

A Tour of Go, Concurrency

What are channels in Golang?, Educative Answers Team

⭐ Concurrent Programming with Go, By Mike Van Sickle

--

--