← Blog'a Dön
TEKNIK

Concurrency ve Parallelism Nedir? Eşzamanlılık Rehberi

F. Çağrı Bilgehan31 Ocak 202611 dk okuma
concurrencyparallelismthreadasync

Concurrency ve Parallelism Nedir? Eşzamanlılık Rehberi

Uygulamanız aynı anda birden fazla işi yönetebiliyor mu? Concurrency ve Parallelism arasındaki farkı anlayarak performanslı ve güvenli çok iş parçacıklı uygulamalar yazın.

Tanımlar

Concurrency (Eşzamanlılık)

Birden fazla görevin aynı zaman diliminde ilerlemesi. Gerçekten aynı anda çalışmaları gerekmez — aralarında hızlıca geçiş yapılır.

Concurrency (tek çekirdek):
Görev A: ████░░░████░░░████
Görev B: ░░░████░░░████░░░
          ──────────────────→ zaman

Parallelism (Paralellik)

Birden fazla görevin gerçekten aynı anda çalışması. Birden fazla CPU çekirdeği gerektirir.

Parallelism (çok çekirdek):
Çekirdek 1: ████████████████
Çekirdek 2: ████████████████
             ──────────────→ zaman

Arasındaki Fark

| Özellik | Concurrency | Parallelism | |---------|------------|-------------| | Amaç | Birden fazla görevi yönetmek | Birden fazla görevi hızlandırmak | | CPU çekirdeği | Tek yeterli | Birden fazla gerekli | | Örnek | Web sunucusu (çok istemci) | Video encoding | | Zorluk | Race condition, deadlock | Senkronizasyon maliyeti |

Thread (İş Parçacığı)

import threading

def download_file(url):
    print(f"İndiriliyor: {url}")
    # ... indirme işlemi

# Aynı anda 3 dosya indir
threads = []
for url in ["file1.zip", "file2.zip", "file3.zip"]:
    t = threading.Thread(target=download_file, args=(url,))
    threads.append(t)
    t.start()

for t in threads:
    t.join()

Async/Await (Asenkron Programlama)

Thread kullanmadan concurrency sağlama:

// Sıralı (yavaş) - 3 saniye
const user = await getUser(42);       // 1s
const orders = await getOrders(42);   // 1s
const reviews = await getReviews(42); // 1s

// Eşzamanlı (hızlı) - 1 saniye
const [user, orders, reviews] = await Promise.all([
  getUser(42),
  getOrders(42),
  getReviews(42)
]);

Race Condition

Birden fazla thread aynı veriye eriştiğinde ortaya çıkan tutarsızlık:

Thread A: bakiye oku (1000) → 1000 + 500 = 1500 → yaz (1500)
Thread B: bakiye oku (1000) → 1000 - 200 = 800  → yaz (800)

Sonuç: Bakiye 800 (500 TL buharlaştı!)
Beklenen: 1300

Çözüm: Mutex (Mutual Exclusion)

import threading

lock = threading.Lock()
balance = 1000

def deposit(amount):
    global balance
    with lock:  # Kilit al
        current = balance
        balance = current + amount
    # Kilit serbest bırakılır

def withdraw(amount):
    global balance
    with lock:
        current = balance
        balance = current - amount

Deadlock

İki thread birbirinden kilit bekler, ikisi de ilerleyemez:

Thread A: Lock 1 aldı → Lock 2 bekliyor...
Thread B: Lock 2 aldı → Lock 1 bekliyor...
→ Sonsuz bekleme!

Çözüm:

  • Kilit sıralaması — Kilitleri her zaman aynı sırada alın
  • Timeout — Belirli sürede kilit alınamazsa vazgeç
  • Lock-free algoritmalar — Atomic işlemler kullanın

Concurrency Modelleri

1. Multi-threading

Her görev bir thread'de çalışır. Paylaşılan bellek, senkronizasyon gerekir.

2. Event Loop (Node.js)

Tek thread, non-blocking I/O. I/O beklerken başka işler yapılır.

Event Loop: İstek 1 → DB'ye sor → Beklerken İstek 2'yi işle → DB yanıt → İstek 1'i tamamla

3. Actor Model (Elixir/Erlang)

Her aktör bağımsız, paylaşılan bellek yok. Mesajlarla haberleşir.

4. CSP - Communicating Sequential Processes (Go)

Goroutine'ler channel'lar üzerinden haberleşir:

ch := make(chan int)

go func() {
    result := expensiveCalculation()
    ch <- result // Kanal'a gönder
}()

value := <-ch // Kanal'dan al

Ne Zaman Hangisi?

| Senaryo | Yaklaşım | |---------|----------| | I/O-bound (API, DB) | Async/Await | | CPU-bound (hesaplama) | Parallelism (multi-process) | | Web sunucusu | Event Loop veya Thread Pool | | Veri işleme | Worker pool |

Best Practices

  1. Paylaşılan durumdan kaçının — Mümkünse immutable veri kullanın
  2. En az kilit — Sadece gerektiğinde senkronize edin
  3. Thread pool kullanın — Her iş için yeni thread oluşturmayın
  4. Atomic işlemler tercih edin — Lock yerine CAS (Compare-And-Swap)
  5. Deadlock tespiti — Timeout ve ordered locking uygulayın
  6. Test edin — Race condition testleri (stress testing) yapın

Sonuç

Concurrency ve parallelism, modern uygulamaların performansı için kritiktir. Doğru modeli seçmek ve senkronizasyon sorunlarını (race condition, deadlock) yönetmek, güvenilir sistemler kurmanın anahtarıdır.

Concurrency kavramlarını LabLudus platformunda pratik yaparak öğrenin.

İlgili Yazılar

Acik Kaynak Yazilim Rehberi: Nedir, Nasil Katki Yapilir?

Acik kaynak yazilim nedir, lisans turleri nelerdir ve acik kaynak projelere nasil katki yapilir? GitHub, open source ve topluluk rehberi.

CI/CD Nedir? Surekli Entegrasyon ve Dagitim Rehberi

CI/CD nedir, neden onemlidir ve nasil kurulur? GitHub Actions, Jenkins ve otomatik test-deploy pipeline rehberi.