🐍 SIFIRDAN İLERİ SEVİYEYE PYTHON EĞİTİM SERİSİ - BÖLÜM 5

================================================================================
🐍 SIFIRDAN İLERİ SEVİYEYE PYTHON EĞİTİM SERİSİ - BÖLÜM 5
================================================================================

Selamlar Değerli Forum Sakinleri! 🚀🔥

Generator mimarisini, `yield` protokolünü ve bellek dostu Lazy Evaluation
tekniklerini arkamızda bıraktık. Şimdi geldik Python'ın en çok tartışılan,
mülakatlarda en çok sorulan ve sistem mimarisinin kalbinde yer alan konusuna:
**Bölüm 5: Eşzamanlılık, GIL ve Asenkron Programlama!** ☕💻

Bu bölümde:
1. GIL (Global Interpreter Lock) Nedir, Neden Var ve Nasıl Çalışır?
2. Multi-Threading vs Multi-Processing (I/O Bound vs CPU Bound)
3. `asyncio` Mimarisi, Event Loop ve Coroutine Gizemi

--------------------------------------------------------------------------------
1. CPython'ın Prangası ve Koruyucusu: GIL (Global Interpreter Lock) 🔒
--------------------------------------------------------------------------------
Python'da çoklu izlek (multi-threading) kullanarak 8 çekirdekli bir işlemcinin
tüm çekirdeklerini %100 yükte çalıştıramazsınız. Bunun sebebi **GIL**'dir.

GIL Nedir?
CPython interpreter'ının (sanal makinesinin) aynı anda SADECE TEK BİR THREAD
tarafından çalıştırılmasını garanti eden bir mutex (kilitleme) mekanizmasıdır.

Neden Var?
Bölüm 2'de gördüğümüz **Reference Counting (ob_refcnt)** bellek yönetimini hatırla!
Eğer iki farklı thread aynı anda bir nesnenin referans sayacını güncellemeye
çalışsaydı, yarış durumu (Race Condition) oluşur ve bellek bozulurdu (Memory Corruption).
CPython geliştiricileri thread-safety sağlamak için en hızlı yol olan GIL'i seçti.

GIL Nasıl Aşılır?
- CPU Bound (ağır matematiksel/işlemci odaklı) işlerde `multiprocessing` kullanılır.
- C-Extension yazarak (C/C++ veya Cython) GIL manuel olarak serbest bırakılır (`Py_BEGIN_ALLOW_THREADS`).

--------------------------------------------------------------------------------
2. Multi-Threading vs Multi-Processing Mimarisi ⚡
--------------------------------------------------------------------------------
İki yaklaşım arasındaki farkı anlamak, doğru mimariyi kurmanın anahtarıdır:

A) Multi-Threading (`threading` modülü):
- Tek bir Process içinde birden fazla Thread çalıştırır.
- Tüm thread'ler AYNI BELLEK ALANINI (Heap) paylaşır.
- **I/O Bound** (Dosya okuma/yazma, Ağ istekleri, Veritabanı sorguları) işler için idealdir.
- Thread I/O beklerken GIL serbest bırakılır, böylece diğer thread çalışır.

B) Multi-Processing (`multiprocessing` modülü):
- İşletim sisteminde tamamen BAĞIMSIZ yeni Process'ler (süreçler) kopyalar (fork/spawn).
- Her process'in KENDİ GIL'i ve KENDİ BELLEK ALANI vardır.
- **CPU Bound** (Görüntü işleme, Kriptografi, Ağır döngüler) işler için zorunludur.

Teorik Karşılaştırma Kodu:
import time
from threading import Thread
from multiprocessing import Process

def cpu_agir_islem(n):
count = 0
for i in range(n):
count += i

N = 20_000_000

# THREADING TEST (GIL Engeline Takılır - Zaman Kısalmaz!)
# t1 = Thread(target=cpu_agir_islem, args=(N,))
# t2 = Thread(target=cpu_agir_islem, args=(N,))

# MULTIPROCESSING TEST (Gerçek Paralellik - Farklı Çekirdekler Kullanılır!)
# p1 = Process(target=cpu_agir_islem, args=(N,))
# p2 = Process(target=cpu_agir_islem, args=(N,))

--------------------------------------------------------------------------------
3. Asenkron Programlama: asyncio, Event Loop ve Coroutines 🛸
--------------------------------------------------------------------------------
Thread'lerin oluşturulması ve Context Switch (izlekler arası geçiş) külfetlidir.
Sadece I/O bekleyen binlerce bağlantıyı (örneğin Web Sockets) yönetmek için
**Non-blocking Asenkron Mimari** tercih edilir.

A) Event Loop (Olay Döngüsü):
İşletim sisteminin I/O olaylarını (epoll/kqueue/IOCP) dinleyen, hazır olan
görevleri sırayla icra eden sonsuz bir döngüdür.

B) Coroutine Yapısı (`async` / `await`):
Normal fonksiyonlar `return` ile biter. Coroutine'ler ise `await` komutunu
gördüğünde denetimi (control) Event Loop'a geri devreder:
"Ben verinin gelmesini bekliyorum, sen bu sırada başka işleri hallet!"

Teorik Asenkron Kod Akışı:
import asyncio

async def veri_cek(id, sure):
print(f"[+] İstek {id} gönderildi...")
await asyncio.sleep(sure) # Non-blocking bekleme (Event loop serbest kalır)
print(f"[✓] İstek {id} tamamlandı! ({sure} sn)")
return f"Veri {id}"

async def main():
# 3 farklı I/O işlemi EŞZAMANLI (Concurrent) başlatılır
gorevler = [
veri_cek(1, 3),
veri_cek(2, 2),
veri_cek(3, 1)
]
# Toplam süre 3+2+1=6 saniye DEĞİL, en uzun görev olan 3 saniye sürer!
sonuclar = await asyncio.gather(*gorevler)
print(sonuclar)

# asyncio.run(main())

--------------------------------------------------------------------------------
4. Bölüm Özeti ve Gelecek Adım 📌
--------------------------------------------------------------------------------
Bu bölümde GIL mekanizmasının iç yüzünü, Threading ve Multiprocessing arasındaki
bellek/işlemci farklarını ve `asyncio` mimarisinin çalışma prensiplerini inceledik.

Devam etmek için forum başlığı altına "DEVAM" yazmanız yeterlidir!

Bir sonraki bölümde (Bölüm 6):
- Python İç Mimarisi: C-API ve C/C++ ile Python'ı Genişletme (C-Extensions)
- Cython Kullanımı ve C-Pointer Seviyesinde Performans Optimizasyonu
- Python Binary Dosyaları ve Marshalling Mekanizması

Sorularınızı ve teo
rik katkılarınızı aşağıda bekliyorum! 🚀✨
================================================================================

🔒 Bu içeriği görmek için giriş yapın

 
Yanıt yazmak için giriş yapmalısınız
Forum özelliklerini kullanmak ve Level 2 üyelik satın almak için hesabınıza giriş yapın.
135,050Konular
3,297,703Mesajlar
326,233Kullanıcılar
membiSon Üye
Üst Alt