AsyncIO Nedir ? Nasıl Kullanılır ?
AsyncIO nedir?
AsyncIO’yu bir örnek ile açıklayalım. Bu örnek PyCon 2017 konuşmasında anlatılmıştır.
Bir satranç ustasının 24 amatör ile satranç oynayacağını düşünelim. Satranç ustası her hamlesi 5 sn sürerken amatör oyuncular 55 sn’de bir hamle yaptıklarını düşünelim. Toplam 60 hamlede bittiğini düşünürsek 55 + 5 = 60. 1 dakika 60 hamle 60 dakikada 1 maç biter. Satranç ustamız bir mac bitmeden diğerine geçmediğimi düşünürsek, 24 maç 24 saat sürecektir.
Satranç ustası hamlesini yaptıktan sonra diğer oyuna geçtiğini düşünelim ve bu tüm oyunlar bitine kadar devam ettiğini düşünürsek süre inanılmaz kısalacaktır.
AsyncIO Nerelerde Kullanılmalı ?
- Input/Output işlemlerinde.
- Request İşlemlerinde
- Veritabani islemleri vb.)
AsyncIO kullanılabilecek her yerde thread yerine tercih edilmelidir. Thread sadece zorunlu durumlarda tercih edilmelidir.
AsyncIO’nun Kalbi Coroutines
Corountine’ler generatorlerin (Yield) özelleşmiş bir versiyonudur.
Coroutine çalışmayı durdurup başka bir coroutine’e kontrol verebilir ve tekrar kontrol ona devredildiğinde kaldığı yerden devam edebilir.
Async & await ?
Async: Fonksiyonun (method) asenkron çalışacağını belirtir.
Await: Kullanıldıgı yerde fonksiyonun durdurulup başka bir işe kontrol verilebileceğini belirtir.
AsyncIO Kod Örneği
2021 yılında mağazalara girişler Korona sebebi ile kısıtlandı. Bizde buradan bir AsyncIO kod örneği çıkaralım.
Bir mağazamız olduğunu varsayalım ve korona sebebiyle sadece 1 kişi içeride bulunabilir. O kişi çıktıktan sonra diğer müşteriler siyasi ile girebilir. 3 müşterimiz olduğunu ve her müşterinin içeride ayni sure kalacağını varsayarsak kodumuz aşağıdaki gibi olacaktır.
# with corona import time def shop_corona_time(name=None): print(f"Welcome {name}") time.sleep(1) print(f"Bye {name}") def main(): shop_corona_time("ahmet") shop_corona_time("mehmet") shop_corona_time("veli") if __name__ == "__main__": s = time.perf_counter() main() elapsed = time.perf_counter() - s print(f"With Corona executed in {elapsed:0.2f} seconds.")
Korona’dan önce bu nasıldı hatırlayalım 🙂
import asyncio async def shop(name=None): print(f"Welcome {name}") await asyncio.sleep(1) print(f"Bye {name}") async def without_corona_main(): await asyncio.gather(shop("ahmet"), shop("mehmet"), shop("veli")) if __name__ == "__main__": import time s = time.perf_counter() asyncio.run(without_corona_main()) elapsed = time.perf_counter() - s print(f"Without Corona executed in {elapsed:0.2f} seconds.")
Burada AsyncIO kullanımı görüyoruz.
async def shop():
Async anahtar kelimesi fonksiyonun asenkron olarak çalışacağını belirtiyor.
await asyncio.sleep(1)
Fonksiyon içindeki await kod parçacığı bu isi burada durdurup diğer ise geçilebileceğini soyluyor. Bu sayede diğer çalışması gereken isler ilerletiliyor. Fonksiyon gather içerisinde 3 defa yazıldığından dolayı diğer shop() fonksiyonu çaliştırılıyor. Ayni şekilde await’e geldiğinde sıradaki fonksiyona geçiliyor. bu sayede kodun beklemesi gereken yerlerde CPU meşgul edilmiyor.
asyncio.gather()
Gather fonksiyonu içerisine input olarak verilen iş (coroutine) ‘lerin hepsinin durumunun complete (tamamlanmış) olmasını bekleyerek sonuçları liste şeklinde döner.
asyncio.run()
Run fonksiyonu işlerin tamamlanana kadar yürütülmesini sağlar.
AsyncIO kodumuzu hızlandırmak için en iyi seçenek olabilir. Fakat async fonksiyondan çağırdığınız her fonksiyonun async olmasına dikkat ediniz aksi halde fazla bir numarası kalmaz 🙂
AsyncIO wait_for(), to_thread(), shield(), vb gibi fonksiyonları bulunmaktadır. AsyncIO Python Docs