Koroutin nedir? Eşzamanlılık ile nasıl ilişkilidir?
Koroutin nedir? Eşzamanlılık ile nasıl ilişkilidir?
Yanıtlar:
Eşbütünler ve eşzamanlılık büyük ölçüde diktir. Koroutinler, akış kontrolünün geri dönmeden iki farklı rutin arasında işbirliği içinde geçirildiği genel bir kontrol yapısıdır.
Python'daki 'verim' ifadesi iyi bir örnektir. Bir koroutin oluşturur. 'Verim' ile karşılaşıldığında, işlevin geçerli durumu kaydedilir ve kontrol çağrı işlevine geri döner. Çağıran işlev daha sonra yürütmeyi yeniden sağlama işlevine geri aktarabilir ve durumu 'verim' ile karşılaşılan noktaya geri yüklenir ve yürütme devam eder.
Coroutines are a general control structure whereby flow control is cooperatively passed between two different routines without returning.
<- Bu ise eşzamanlılık. Aradığınız kelime paralelliktir.
orthogonal = Not similar to each other
?
orthogonal
"birbirinden bağımsız" anlamına geldiği söylendi .
Lua'da Programlama'dan " Coroutines
" bölümü:
Bir koroutin bir iş parçacığına benzer (çoklu iş parçacığı anlamında): kendi yığını, kendi yerel değişkenleri ve kendi talimat işaretçisi ile bir yürütme çizgisidir; ancak küresel değişkenleri ve çoğunlukla diğer koroutinlerle olan her şeyi paylaşır. İş parçacıkları ve eşgüdümler arasındaki temel fark, kavramsal olarak (veya tam anlamıyla, çok işlemcili bir makinede), iş parçacığı olan bir programın birkaç iş parçacığını paralel olarak çalıştırmasıdır. Öte yandan, eş-programlar işbirlikçidir: herhangi bir zamanda eş-programlı bir program eş-programlarından yalnızca birini çalıştırır ve bu eş-zamanlı program, yalnızca açıkça askıya alınma talebinde bulunduğunda yürütülmesini askıya alır.
Mesele şu ki: Coroutines “işbirlikçi”. Çok çekirdekli sistemde bile, herhangi bir zamanda yalnızca bir koroutin vardır (ancak birden fazla iş parçacığı paralel olarak çalışabilir). Koroutinler arasında önleyici olmayan bir durum vardır, çalışan koroutinin yürütmeyi açıkça bırakması gerekir.
İçin "concurrency
" Rob Pike'ın slaydına başvurabilirsiniz :
Eşzamanlılık, hesaplamaları bağımsız olarak yürütmenin bileşimidir.
Yani eşyordam A'nın yürütülürken, bu eşyordam B'ye kontrolünü Sonra bir süre sonra, eşyordam B olmadığından eşyordam A'ya kontrol sırtını geçer geçer bağımlılık iki eşyordamlar yüzden, değiş tokuş eden kavramlar arasındaki ve onlar tandem çalıştırmalısınız eşzamanlılık değil .
Teknik bir soru olmasına rağmen cevapların çoğunu çok teknik buluyorum. Koroutin süreci anlamaya çalışırken zorlandım. Biraz anladım ama aynı anda anlayamıyorum.
Bu yanıtı burada çok yararlı buldum:
https://dev.to/thibmaek/explain-coroutines-like-im-five-2d9
Idan Arye'den alıntı yapmak için:
Hikayeni geliştirmek için şöyle bir şey koyardım:
Çizgi film izlemeye başlıyorsunuz ama bu giriş. İntroyu izlemek yerine oyuna geçip çevrimiçi lobiye girersiniz - ancak 3 oyuncuya ihtiyaç duyar ve sadece siz ve kız kardeşiniz oyundasınız. Başka bir oyuncunun katılmasını beklemek yerine ödevinize geçin ve ilk soruyu cevaplayın. İkinci sorunun izlemeniz gereken bir YouTube videosuna bağlantısı vardır. Açıyorsunuz - ve yüklenmeye başlıyor. Yüklenmesini beklemek yerine karikatüre geri dönersiniz. Giriş bitti, böylece izleyebilirsiniz. Şimdi reklamlar var - ama bu arada üçüncü bir oyuncu katıldı, böylece oyuna geçiş yapın Ve böyle devam edin ...
Fikir, her şeyi aynı anda yapıyormuş gibi yapmak için görevleri gerçekten hızlı bir şekilde değiştirmemenizdir. Doğrudan dikkatinizi gerektiren başka şeyleri yapmak için bir şeylerin olmasını beklediğiniz zamanı (IO) kullanırsınız.
Kesinlikle bağlantıyı kontrol edin, her şeyi teklif edemediğim çok daha fazlası var.
Koroutin, alt rutine / iş parçacıklarına benzer. Aradaki fark bir arayan bir alt rutini / iş parçacığını çağırdığında, asla arayan işlevine geri dönmeyecektir. Ancak bir program, arayanın kendi kodunun bir kısmını yürütmesine ve yürütmeyi durdurduğu ve oradan devam ettiği koroutin noktasına geri dönmesine izin veren birkaç kod yürüttükten sonra arayana geri dönebilir. yani. Bir programın birden fazla giriş ve çıkış noktası vardır
Temel olarak, iki tür Coroutine vardır:
Kotlin, yığınsız coroutines uygular - bu, coroutines'in kendi yığını olmadığı anlamına gelir, bu nedenle yerel iplik üzerinde eşleşmezler.
Koroutini başlatmak için işlevler şunlardır:
launch{}
async{}
Buradan daha fazla bilgi edinebilirsiniz:
https://www.kotlindevelopment.com/deep-dive-coroutines/
https://blog.mindorks.com/what-are-coroutines-in-kotlin-bf4fecd476e9
Bir program, özel bir tür alt programdır. Arayan ve geleneksel alt programlarda var olan bir alt program arasındaki master-köle ilişkisinden ziyade, arayan ve koroutin olarak adlandırılan coutinler daha eşittir.
Koroutin, birden fazla girişi olan ve bunları kontrol eden bir alt programdır - doğrudan Lua'da desteklenir
Simetrik kontrol olarak da adlandırılır: arayan ve koroutin olarak adlandırılanlar daha eşittir
Ortak program çağrısına özgeçmiş adı verilir
Bir ortak programın ilk özgeçmişi başlangıcıdır, ancak sonraki çağrılar, ortak programda son yürütülen ifadeden hemen sonra girilir.
Coroutines, muhtemelen sonsuza dek birbirini tekrar tekrar sürdürür
Koroutinler, program birimlerinin (eş-rutinler) yarı-eşzamanlı yürütülmesini sağlar; icraları serpiştirilmiş, ancak örtüşmemiştir
Bu bağlantının bir açıklamasını oldukça basit buluyorum . Bu yanıtlardan hiçbiri son kurşun noktası hariç paralellik vs eşzamanlılık anlatmaya çalışacağım bu cevap .
anılanefsanevi Joe Armstrong tarafından "Erlang programlama" dan :
eşzamanlı bir program paralel bir bilgisayarda potansiyel olarak daha hızlı çalışabilir.
eşzamanlı program, eşzamanlı programlama dilinde yazılmış bir programdır. Performans, ölçeklenebilirlik veya hata toleransı nedeniyle eşzamanlı programlar yazıyoruz.
eşzamanlı programlama dili, eşzamanlı programlar yazmak için açık dil yapılarına sahip bir dildir. Bu yapılar programlama dilinin ayrılmaz bir parçasıdır ve tüm işletim sistemlerinde aynı şekilde davranır.
paralel bilgisayar, aynı anda çalışabilen birkaç işlem birimi (CPU veya çekirdek) olan bir bilgisayardır.
Yani eşzamanlılık paralellik ile aynı şey değildir. Eşzamanlı programları tek çekirdekli bir bilgisayara yazabilirsiniz. Zaman paylaşma zamanlayıcısı, programınızın aynı anda çalıştığını hissetmenizi sağlayacaktır.
Eşzamanlı program, paralel bir bilgisayarda paralel çalışma potansiyeline sahiptir, ancak garanti edilmez . İşletim Sistemi, programınızı çalıştırmanız için size yalnızca bir çekirdek verebilir.
Bu nedenle, eşzamanlılık, eşzamanlı bir programdan alınan ve programınızın fiziksel olarak paralel çalışabileceği anlamına gelmeyen bir yazılım modelidir .
“Koroutin” kelimesi iki kelimeden oluşur: “ko” (kooperatif) ve “rutin” (fonksiyonlar).
a. eşzamanlılık veya paralellik sağlıyor mu?
Basit olmak için, onu tek çekirdekli olarak tartışalım bilgisayarda .
Eşzamanlılık, OS'den zaman payları ile elde edilir. Bir iş parçacığı, kodunu CPU çekirdeğindeki atanmış zaman dilimlerinde yürütür. OS tarafından önlenebilir. Ayrıca işletim sistemine kontrol verebilir.
Öte yandan bir koroutin, OS'ye değil, iplik içindeki başka bir koroutine kontrol verir. Bu nedenle, bir iş parçacığındaki tüm couteinler, CPU çekirdeğini OS tarafından yönetilen diğer iş parçacıklarına vermeden o iş parçacığının zaman çerçevesinden yararlanır.
Bu nedenle, coroutine'nin OS tarafından değil, kullanıcı tarafından zaman paylaşımları elde ettiğini düşünebilirsiniz. (veya yarı paralellik) . Ortak programlar, bu ortak programları çalıştıran iş parçacığına atanan çekirdek üzerinde çalışır.
Coroutine paralelliğe ulaşıyor mu? CPU bağlantılı kod ise, hayır. Zaman paylaşımları gibi, paralel çalıştıklarını hissettirir, ancak infazları birbiriyle örtüşmez. IO-bağlıysa, evet, kodunuzla değil donanım (IO aygıtları) ile paraleldir.
b. call ile fark nedir?
Resimde görüldüğü gibi, return
kontrolü değiştirmek için aramaya gerek yoktur . Olmadan verim verebilir return
. Bir yardımcı program, durumu geçerli işlev çerçevesine (yığın) kaydeder ve paylaşır. Bu nedenle, çağrı yığınını ne zaman istiflemek ve geri almak için kayıtları ve yerel değişkenleri kaydetmeniz gerekmediğinden işlevden çok daha hafiftir call ret
.
Gönderen Python eşyordam :
Python yardımcı programlarının yürütülmesi birçok noktada askıya alınabilir ve devam ettirilebilir (bkz. Ortak program). Bir koroutin fonksiyonun gövdesi içinde, bekleme ve zaman uyumsuzlukları ayrılmış anahtar kelimeler haline gelir; ifadeleri, async ve async ifadelerini yalnızca coroutine işlev gövdelerinde kullanılabilir.
Kaynaktan Eşyordamlar (C ++ 20)
Koroutin, daha sonra sürdürülecek yürütmeyi askıya alabilen bir işlevdir . Coroutines yığınsızdır: arayan kişiye geri dönerek yürütmeyi askıya alırlar. Bu, eşzamansız olarak çalışan sıralı kodlara izin verir (örn. Açık geri çağrılar olmadan engellemeyen G / Ç işlemek için) ve ayrıca tembel hesaplanmış sonsuz diziler ve diğer kullanımlar için algoritmaları destekler.
Başkalarının cevabı ile karşılaştırın:
Benim düşünceme göre, daha sonra devam eden bölüm, @ Twinkle'ninki gibi temel bir farktır.
Bununla birlikte, belgenin birçok alanı hala devam etmekle birlikte, bu bölüm @Nan Xiao'nun
Öte yandan, eş-programlar işbirlikçidir: herhangi bir zamanda eş-programlı bir program eş-programlarından yalnızca birini çalıştırır ve bu eş-zamanlı program, yalnızca açıkça askıya alınma talebinde bulunduğunda yürütülmesini askıya alır.
Lua'daki Program'dan alıntılandığından, belki de dil ile ilgilidir (şu anda Lua'ya aşina değil), tüm belgeler tek bir kısımdan bahsetmedi .
Eşzamanlı ilişki: Koroutinlerin (C ++ 20)
bir "Yürütme" kısmı vardır. Burada alıntı yapmak çok uzun.
Detayın yanı sıra birkaç eyalet var.
When a coroutine begins execution
When a coroutine reaches a suspension point
When a coroutine reaches the co_return statement
If the coroutine ends with an uncaught exception
When the coroutine state is destroyed either because it terminated via co_return or uncaught exception, or because it was destroyed via its handle
@ user217714'ün cevabı altında @Adam Arold'ın yorumu olarak. Eşzamanlılık.
Ancak, çoklu kullanımdan farklıdır.
itibaren std :: iplik
İş parçacıkları, birden çok işlevin aynı anda yürütülmesine izin verir. İş parçacıkları, yapıcı bağımsız değişkeni olarak sağlanan en üst düzey işlevden başlayarak, ilişkili iş parçacığı nesnesinin oluşturulmasından hemen sonra (herhangi bir işletim sistemi zamanlama gecikmesini beklerken) yürütülmeye başlar. Üst düzey işlevin döndürme değeri yoksayılır ve bir özel durum atanarak sonlanırsa, std :: terminate çağrılır. Üst düzey işlev, dönüş değerini veya istisnasını arayana std :: promise veya paylaşılan değişkenleri değiştirerek iletebilir (senkronizasyon gerektirebilir, bkz. Std :: mutex ve std :: atomic)
Eşzamanlılık olduğundan, özellikle beklemek kaçınılmaz olduğunda (OS perspektifinden) çoklu iş parçacığı gibi çalışır, bu yüzden kafa karıştırıcıdır.
@ User21714'ün cevabı üzerine genişleyeceğim. Eşgüdümler, aynı anda çalışamayan bağımsız yürütme yollarıdır. python
Bu yollar arasında geçiş yapmak için bir denetleyiciye - örneğin bir denetleyici kitaplığına - bağımlıdırlar . Ancak bunun işe yaraması için, koroutinlerin kendilerinin yield
yürütme işlemlerinin duraklatılmasına izin veren benzer yapıları çağırması gerekir .
İş parçacıkları bunun yerine bağımsız bilgi işlem kaynakları üzerinde ve birbirlerine paralel olarak ilerliyor. Farklı kaynaklarda oldukları için , diğer yürütme yollarının ilerlemesine izin vermek için verim çağrılmasına gerek yoktur .
Bu efekti, hiper-iplik çekirdeğinizin jvm
sekizinin core i7
de kullanıldığı çok iş parçacıklı bir program (ör. Bir uygulama) başlatarak görebilirsiniz: Activity Monitor
veya içinde% 797'lik kullanım görebilirsiniz Top
. Bunun yerine, tipik bir python
programı çalıştırırken - coroutines
veya bir tane olsa bile python threading
- kullanım% 100'de maks. Yani bir makine hiper dişi.