Python Threading İşlemleri

Python Threading ile çok yüksek hesaplama kapasitesi gerektiren işlemler sunucu işlemcisinin çekirdeklerine dağıtılarak daha hızlı bir şekilde sonuçlandırılır. İşlemci çekirdeklerine paylaştırılan işlemler optimize olduğu için daha kısa sürede sonuca ulaşılacaktır.

Index
Python Threading Kütüphanesi ile Optimizasyon
İşlemci üzerinde yükü dağıtarak eş zamanlı hesaplama kabiliyetidir. Genellikle programın çalışacağı donanım hakkında bilginiz yoksa bu yöntem kullanılabilir. Paralel veya Concurrent olarak çekirdeklere yük dağıtılarak birden fazla çalıma yapılabilir.
Daha çok mobil uygulama geliştirme aşamasında sıklıkla kullanılmaktadır.
Threading Kullanmadan İşlem Hızının Ölçümlenmesi
Bunun için python threading modülü import edelim ancak threading yapmadan işlem süresini hesaplayalım.
import threading
import requests as req
import time
def get_web(urls):
start_time = time.time()
json_data = []
for url in urls:
json_data.append(req.get(url).json())
end_time = time.time()
dif_time = end_time - start_time
print(f"Time: {dif_time}")
return json_data
urls = ['https://postman-echo.com/delay/2'] * 8 # 8 times request delay 2 seconds
get_web(urls) # Time: 24.787731170654297 secondsPythonYukarıdaki kod satırlarında https://postman-echo.com/delay/2 adlı veri kaynağına 2 saniye bekleme süresi talep edilmiş ve toplamda 8 defa çalıştırılarak toplam işlem süresini hesaplaması istenmiştir. Toplam 24 saniyede işlemler sonuçlanmıştır.
Threading Kullanarak İşlem Hızının Ölçümlenmesi
Şimdi bu görevi aynı anda işlemci üzerinde paralel bölümleyerek yapmayı deneyelim. Python Threading kütüphanesini kullanarak İşlem süresini hesaplayalım. Bunun için bir class ve birkaç fonksiyon tanımlamamız gerekecek.
import threading
import requests as req
import time
## Use threading for this class and function:
class ThreadingOptimizer(threading.Thread):
json_data = []
def __init__(self,url): ## for inheritance
super().__init__()
self.url = url
def run(self):
response = req.get(self.url)
self.json_data.append(response.json())
return self.json_data
def get_web_thread(urls):
start_time = time.time()
threads = []
for url in urls:
t = ThreadingOptimizer(url)
t.start()
threads.append(t)
for t in threads:
t.join()
print(t)
end_time = time.time()
dif_time = end_time - start_time
print(f"Time: {dif_time}")
urls = ['https://postman-echo.com/delay/2'] * 8 # 8 times request delay 2 seconds
get_web_thread(urls)
PythonThreadingOptimizer adı verdiğimiz Class içerisinde tanımlanan özel run fonksiyonu içinde yapılacak işlemler threading yordamı ile hızlı bir şekilde hesaplanır.
Aynı işlemi Threading olmadan hesapladığımızda 24 saniye sürerken, Threading desteği ile yapıldığında 3.3 saniye sürmektedir.
Coroutines ve Görevler (Asynchronous)
Bu threading yordamını kullanabilmek için asyncio ve aiohttp kütüphanelerini import etmeniz gerekmektedir. Bu yöntemle thread işlemleri yeri geldiğinde istediğini durdurabilir yada devam ettirebilir.
async: senkron olmayan bir threading yazılacağını ifade eder.
await: çalışmakta olan bir asyncio işleminin sonucunun bekleneceğini belirtir.
import threading
import requests as req
import time
import asyncio
import aiohttp
async def get_web_async_wrapper(urls):
start_time = time.time()
jason_data = []
async with aiohttp.ClientSession() as session:
for url in urls:
async with session.get(url) as resp:
jason_data.append(await resp.json())
end_time = time.time()
dif_time = end_time - start_time
print(f"Time: {dif_time}")
return jason_data
urls = ['https://postman-echo.com/delay/2'] * 8 # 8 times request delay 2 seconds
asyncio.run(get_web_async_wrapper(urls))PythonRecursion Process (İç içe Yeniden Çalıştırma)
Tam olarak Türkçe’de iç içe yeniden çalıştırılabilir olarak çevirebileceğimiz oldukça kullanışlı bir Python özelliği. Bir döngü içerisinde yapılabilecek birçok işlemi Recursive yöntemi ile daha kolay bir şekilde gerçekleştirebilirsiniz.
Aşağıdaki örneğimizde matematiksel Faktöriyel hesabı yapan bir uygulamayı önce döngü mantığı ile sonrasında ise Recursion mantığı ile yazalım.
Faktöriyel hesabını bilmeyenler için hatırlatalım:
5! : 5 Faktöriyel demektir.
Hesap: 5! = 5x4x3x2x1 = 120
While Döngüsü ile:
def FactLoop(number):
num = 1
while (number!=0): # zero point control
if num == 0:
break
else:
num = num * number # non recursion, Loop methods
number-=1
return num
print(f"Fact Recursive Result: {Fact(5)}") # 120 PythonRecursive Yöntemi ile:
def Fact(number):
if number == 0: # zero point control
return 1
else:
return number * Fact(number-1) # Recursion
print(f"Fact Recursive Result: {Fact(5)}") # 120Pythongörüldüğü gibi her iki şekilde de 5 Faktöriyel için 120 sonucu elde ediliyor. Ancak Recursive yöntemi daha az kod satırı ile ipi göğüslüyor.
Aynı Python Threading işlemlerinde olduğu gibi Recursive yani iç içe yeniden çalıştırma tekniği ile çok daha az sayıda kod yazarak birçok döngü gerektiren işlemi yaptırabilirsiniz.





