Merhabalar, uzun zamandır yazmayı planladığım yazı serilerime artık başlamaya karar verdim ve buna ilk olarak Conccurrency kavramını ele alarak başlıyorum. Bu yazıya ulaşacak insanların az çok neye ihtiyacı olduklarını bildikleri için biraz onların anlayacağı bir dil kullanmaya özen gösterdim. Peşin olarak belirteyim ki bu makale genel olarak bilgi içermektedir. Kod örnekleri ve herhangi bir örnek çalışma maalesef kafa karışıklığı ve kavramları kompleksleştireceği için giriş seviyesine uygun bir makale ele almaya çalıştım…

Photo by: @alandelacruz4

(ing) concurrency/kənˈkʌr(ə)nsi/ - eşzamanlılık

  1. the fact of two or more events or circumstances happening or existing at the same time.
  2. (Mathematics) a point at which three or more lines meet.
  3. (Computing) the ability to execute more than one program or task simultaneously.

Unsplash.com’dan alıntıdır.

Photo by @serenarepice

Bilgisayar Bilimlerinde tek bir süreç (process) içerisinde aynı anda birden fazla görev (task) üzerinde ilerleme sağlanabilmesi olarak açıklanabilir. Fakat Türkçe diline eşzamanlı kelimesi olarak geçtiği için aslında tam anlamını yansıtmamaktadır, aslında tam olarak eş zamanlı değil aynı zamanda gibi bir anlama gelmektedir ve bu sebeple paralel programlama ile karıştırılmaktadır.

Aşağıdaki fotoğrafta görüleceği üzere bir barista var ve şöyle hayal edelim; üç adet kahve siparişi baristaya ulaştı ve tek başına her müşterinin siparişini teker teker bitirmeye çalıştığı bir senaryo düşünelim, her kahve için ayrı su kaynatacak ve kahvelerin tek tek demlenmesini bekleyip müşterilere sunacaktır, fakat bu yöntemde belki müşteriler beklemekten sıkılacak ardından belki bekleyen iki müşteri mekanı terk ederek farklı bir kafeye doğru yol alacaktır, bu işletme için can sıkıcı bir durum oluşturacaktır, sonuçta gerçek bir senaryoda ne olursa olsun işletmenin amacı elindeki şartlara göre en optimize kar’ı elde etmek olduğundan bu sistem onu zarara uğratacaktır. (Bunu sizin uygulamanızın çalıştığı işletim sistemi olarakta düşünürseniz aynı koşullar aynı şekilde geçerlidir.)

Photo by: @kimdonkey

Bu baristanın şöyle bir senaryoyu gerçekleştirmesi mümkündür, elinde kaynamış su ile üç adet müşterinin V60 filtresini hazırlayıp kahvelerini ekledikten sonra sıcak suyu hepsi için kullandığında aslında görevi aynı anda yürütebileceği ve üç kahvenin aslında neredeyse yakın zamanlarda demlenebileceği ve müşterilere teslim edileceği mümkündür.(Elbette işletme gerekli malzemeye sahipse.) :)

Parallelism Nedir?

Paralellik tanımı her ne kadar concurrency ile karıştırılsada ikisinin çok temelde büyük farkları mevcuttur. Paralelism bir uygulamanın görevlerini CPU’da paralel olarak ilerleyebilen alt görevlere ayırması olarak açıklayabiliriz. Paralelism uygulamanın içerisindeki görevleri fiziksel olarak CPU’ya atayarak aslında fiziksel olarak bir çalıştırma elde etmiş olur. Paralelism içerisinde görevler aynı anda yürütülürken Concurrency kavramından en büyük farklı fiziksel olarak paralelde aynı anda görev yürütülebilmesidir. Verdiğimiz örnekte elimizdeki görevleri efektif olarak tasarlarsak barista’nın tüm müşterilere en optimize şekilde kahve hazırlayacağını vermiştik fakat Paralelism ile düşünürsek burada işe yeni bir Barista almamız gerekecek, 3 kahve siparişini ikiye bölerek fiziksel bir çözüm sağlamış olacağız.

Concurrency aynı anda bir çok görevi aynı anda yürütmek Paralellism ise aynı anda bir çok görevi yan yana yürütmek gibi düşünüldüğünde bence en sade şekilde bir anlam kurgusu oluşturulabilir.

Neden Concurrency’e İhtiyaç var?

En basit tabirle daha ölçeklendirilebilir ve duyarlı bir yazılıma sahip olmak için Concurrency kavramına hakim olmanız gerekir. Bir arayüz (UI) ekranı düşünün, ekranda çeşitli fonksiyonlar var ve bunlardan bir tanesi sizin veritabanından verileri çekecek diğeri ise IMDB api’sine bağlanarak ekrana IMDB puanları listesini getirecektir. Sizin ilk başta IMDB puanlarını getirdiğiniz ve sonradan veritabanınızdan verileri getireceğiniz bir senaryo düşündüğünde işlemler sırası ile yapılacağından dolayı ilk önce IMDB api’sine bağlantı kurularak veri getirilmeye çalışılır tabi bu süreçte eğer senkron bir sisteminiz varsa arayüz veriyi getirene kadar lock olacaktır, yani kilitlenecektir, belkide api hiç yanıt vermeyecek ve ekranınızda deadlock’lar oluşacaktır. İşte en basit bir örnek dahi olsa bu tür detaylarla boğuşmamak ve daha duyarlı bir sisteme sahip olmak için eş zamanlılık kavramnını destekleyen bir altyapı geliştirmeniz özellikle modern arayüzler için önemli bir konudur.

Dünden Bugüne C# Concurrency Teknikleri

Yukarıda yazılanları az çok anladıysanız aslında Concurrency kavramını neden öğrenmeniz gerektiğiyle ilgili kafanızda bir şeyler oluştuğunu düşünüyorum. C# programlama dilinin yetenekleri doğrultusunda eşzamanlılık kavramını uygulayabileceğiniz yöntemler; Thread(Multi-Thread), Parallel Programming, Asynchronous Programming, TPL Dataflow, Reactive Programming şeklindedir. Hepsinin birbirine göre avantaj ve dezavantajları mevcuttur, elbette ki burada bir doktrin vermek haddim değil, sadece öneriler best practices’lar artık Asenkron Programlama üzerinedir. Thread yönetiminin dezavantajları üzerine daha yüksek seviye ve kolay yönetilebilir teknikler ve kütüphaneler çıkmıştır.

Kötü Concurrent Sistem Tasarlamanın Dezavantajları

  • Race Condition : Örnek verecek olursak aynı anda iki oturumdan tek bir veriyi tüketme amacıyla yapılan isteğe sistemin veri sayısına göre değilde istek sayısına göre çalışabilmesi ve bu tür durumların oluşabilmesi durumu olarak örneklendirilebilir.
  • Deadlock: Basitce anlatmak gerekirse süreçlerin zincirleme olarak birbirine bağımlı olarak yanıt alamayarak birbirlerine geri dönüş sağlayamaması ve çıkmaza girmesidir. Canlı bir örnek. 9gag
  • Debug: Concurrent uygulamalarda debug işlemleri zordur ve herhangi bir hatayı yakalamak için sistemin tasarımı ve hata yakalama mekanizmalarının oturmuş olması gerekir.
  • Starvation: Güzel bi örnek. bknz
  • Exception Handling: Asenkron programlama ile uğraştığınızda Exception’ları yakalama yöntemleri tasarlamazsanız hata mesajlarınızı kaybetme riskiniz kabus yaşatabilir. (AggregateException vb.)

Eğer sistemi ve akışınızı iyi tasarlamadığınızı düşünürsek yukarıdaki gibi bazı kritik sorunları yaşama riskiniz yüksek.. Unutmayın bir şeyin daha hızlı ve performanslı olması için bir şeyler yapıyorsanız orada bir bedel olduğunu sakın unutmayın..

Bir yazı serisi olarak planladığım için burada noktalamaya karar verdimi bu yazı serisi içerisinde Thread, Async Programming, TPL Dataflow, Reactive Programming gibi kavramlar üzerinden örnekler vermeye çalışacağım. Biraz daha zaman olursa Channel yapısı, Producer-Consumer problemleri hakkında yazmak istediğim detaylar var..

Her türlü hata ve yanlış anlatımlarım için lütfen benimle iletişime geçiniz.

Okuduğunuz için teşekkürler.

Akın.

Referanslar

Concurrency in C# Cookbook: Asynchronous, Parallel, and Multithreaded Programming - Stephen Cleary

https://medium.com/@itIsMadhavan/concurrency-vs-parallelism-a-brief-review-b337c8dac350