Async ve await deyimleri tam olarak ne anlama geliyor?

Coroutine ne demek?

Coroutineler, işlemlerin askıya alınmasına ve sürdürülmesine izin vererek, birbirlerini engellemeyen çoklu görevler oluşturmak için fonksiyonları (subroutine) genelleştiren bilgisayar programı bileşenleridir. Genellikle iş birliğine ihtiyaç duyan fonksiyonların kullanıldığı durumlarda oldukça kullanışlıdır.

Normalde bir subroutine (bir fonksiyonun çalışması) şu şekilde olur.

Bir fonksiyon çağrılır, fonksiyonun içinde bir takım işlemler gerçekleşir ve son olarak da kendisinden sadece bir değer döner.

Coroutineler ise çalışma şekli olarak Generatorlere benzerler. Bir Coroutine çalışmaya başladığı zaman, bir işlem gerçekleşir, Coroutine sonra başka bir Coroutinei başlatır (kendisi o an durur). Ve bu yeni çalışmaya başlayan Coroutine'de de bir takım işlemler gerçekleşir, sonra o da başka bir Coroutine'i çalıştırır (kendisi durur). Ve çalışma sırası tekrar ilk durmuş olan Coroutinee geldiği zaman, durmuş olduğu durumdan devam etmeye başlar. Generator için Semi-Coroutine gibi bir ifade var. Aslında aralarındaki farkı pek anlamış da değilim. Şöyle bir ifade okuduğumu hatırlıyorum, “Generatorler daha çok üretici, Coroutine ise daha çok tüketici olarak görev yapar.” Ama pek de tatmin edici bir açıklama değildi.

Aşağıdaki bağlantıda da bir açıklama yapılmış ancak yine de aradaki farkı anlamakta biraz zorluk çektiğimi söyleyebilirim.

Wikipedia’da okuduğum açıklamaya göre, Generator'ler Coroutine'lerin yaptığı işlemelerin hemen hemen aynısını yaparlar. Ancak Coroutinelerde Generator'lerde olmayan, çalışmanın nereden devam etmesi gerektiğini kontrol edebilen bir mekanizma yoktur. Bu ifadeyi biraz incelemek lazım. Çünkü şuanlık çok soyut kalıyor.

Bu arada örnek olarak aşağıdaki fonksiyonlara bakabilirsiniz.

def uret(sayilar, coroutine):
    for sayi in sayilar:
        coroutine.send(sayi)
    coroutine.close()


def yaz():
    print("Yazdırma başladı.")
    try: 
        while True: 
            sayi = yield
            print(sayi)
    except GeneratorExit: 
        print("Yazdırma Bitti.")


yazici = yaz()
next(yazici)
uret(sayilar=range(10), coroutine=yazici)

Bu yukarıdaki örnekte Coroutine, başka bir Coroutine'i çalıştırmıyor.

Yukarıdaki yazici = yaz() fonksiyonu ekrana hiçbir yazı yazdırmaz.

next(yazici) ile ekrana Yazdırma başladı. ve Yazdırma Bitti. yazıları yazılır. Çünkü elimizde henüz herhangi bir ürün yok.

uret(range(10), yazici) ile hem ürünümüzü oluşturmuş hem de yazici'ya ürünleri tek tek paslamış oluruz.

Ve bu fonksiyon çalıştığında şöyle bir çıktı almamız gerekir.

Yazdırma başladı.
0
1
2
3
4
5
6
7
8
9
Yazdırma Bitti.

Başka bir örnek:

def uret(sayilar, coroutine):
    for sayi in sayilar:
        coroutine.send(sayi)
    coroutine.close()
    
    
def karesini_al(coroutine):
    try:
        while True:
            sayi = yield
            coroutine.send(sayi ** 2)
    except GeneratorExit:
        pass


def yaz():
    print("Yazdırma başladı.")
    try: 
        while True: 
            sayi = yield
            print(sayi)
    except GeneratorExit: 
        print("Yazdırma Bitti.")


yazici = yaz()
next(yazici)
kare_al = karesini_al(coroutine=yazici)
next(kare_al)
uret(sayilar=range(10), coroutine=kare_al)

Çıktı:

Yazdırma başladı.
0
1
4
9
16
25
36
49
64
81
Yazdırma Bitti.

bu ne?..


bu konu hakkında bir belge bir yazı veya bir kaynak var mı PYTHON kullanan?

Generator’e send ile gönderdiğimiz değer sayi’ya eşitleniyor. Şöyle bir örnek yapabiliriz.

def uretec(y):
     x = yield
     if y > x:
        yield x
     else:
        yield y
         
         

u = uretec(8)  # y = 8
next(u)
print(u.send(6))  # x = 6
1 Beğeni

konular diyim çünkü zamanında generatorleri görüp bırakmıştım böyle geniş olması kafamı karıştırdı


Generatorlerin asıl amacını anlamadım galiba send fln görünce

Bildiğim kadarıyla (ve sizin de bildiğinizi tahmin ettiğim gibi) generatörlerin asıl amacı, bir dizinin bütün elemanlarının aynı anda hafızada yer kaplamamasını sağlamak. Ayrıca bir generatör fonksiyon bir değişkene eşitlendiğinde ve bu değişken next fonksiyonuna argüman olarak verildiğinde veya degisken.__next__() şeklinde bir kullanımın sonucunda fonksiyonun, daha doğrusu iterasyonun state'i (nerede kaldığı) kaydedilir. Iterasyon sona erdiğinde, generatörün eşitlendiği değişken de tüketilmiş olur.

1 Beğeni

bunu zaten biliyordum saolun sanırım aklımı karıştıran şey send gibi metodlar oldu :slight_smile:

dir fonksiyonunu kullanarak generatörlerin metodlarına bakabilir, hangi metod ne yapıyor kurcalayabilirsiniz.

1 Beğeni

aslında help dir gibi fonksiyonlar büyük nimet şu aralar kullanmaya başladım sizin önceki tavsiyenizi hatırlayarak :slight_smile:

1 Beğeni

peki bir obje oluşturucaz diyelim

namelist = NameList()
veya dict gibi objeler await kullanmamıza gerek var mıdır sizce?

Duruma gore. Yeni NameList objesi olusturma isi uzun surecekse (ve beklemek istenmiyorsa) kullanilabilir.

Bundan daha güzel bir anlatım bulamazdım. Çok teşekkür ederim.

1 Beğeni

Bunu editleme vakti gelmis olabilir, “senkron” yerine “paralel” diyor.

Done. :ok_hand:

1 Beğeni