Eşzamansız ve engellemeyen çağrılar arasındaki fark nedir? Ayrıca engelleme ve senkronize çağrılar arasında (lütfen örneklerle)?
Eşzamansız ve engellemeyen çağrılar arasındaki fark nedir? Ayrıca engelleme ve senkronize çağrılar arasında (lütfen örneklerle)?
Yanıtlar:
Birçok durumda, aynı şey için farklı isimlerdir, ancak bazı bağlamlarda oldukça farklıdırlar. Yani değişir. Terminoloji, tüm yazılım endüstrisinde tamamen tutarlı bir şekilde uygulanmaz.
Örneğin klasik soketler API'sında, engellemeyen bir soket, özel bir "engelleme" hata iletisiyle hemen dönen bir engelleme soketi iken, bir engelleme soketi engellenir. Yeniden denemek için iyi bir zamanın ne olduğunu öğrenmek için select
veya gibi ayrı bir işlev kullanmanız gerekir poll
.
Ancak asenkron soketler (Windows soketleri tarafından desteklendiği gibi) veya .NET'te kullanılan asenkron IO modeli daha uygundur. Bir işlemi başlatmak için bir yöntem çağırırsınız ve çerçeve tamamlandığında sizi geri çağırır. Burada bile temel farklılıklar var. Eşzamansız Win32, Windows iletileri geçirerek sonuçlarını belirli bir GUI iş parçacığına "marshal" sokarken, .NET eşzamansız IO serbest iş parçacığına sahiptir (geri aramanızın hangi iş parçacığının çağrılacağını bilmiyorsunuz).
Yani her zaman aynı anlama gelmezler. Soket örneğini damıtmak için şunu söyleyebiliriz:
senkron / asenkron iki modül arasındaki ilişkiyi tanımlamaktır.
engelleme / engellememe, bir modülün durumunu tanımlamaktır.
Bir örnek:
Modül X: "I".
Modül Y: "kitapçı".
X soruyor Y: "c ++ primer" adlı bir kitabınız var mı?
1) engelleme: Y X yanıtını vermeden önce, X cevap için orada beklemeye devam eder. Şimdi X (bir modül) kilitleniyor. X ve Y iki iş parçacığı mı yoksa iki işlem mi, bir iş parçacığı mı yoksa bir işlem mi? Bilmiyoruz.
2) tıkanmaz: Y, X'e cevap vermeden önce, X sadece oradan ayrılır ve başka şeyler yapar. X, Y'nin işini bitip bitmediğini kontrol etmek için her iki dakikada bir geri gelebilir mi? Yoksa X onu arayacak kadar geri gelmeyecek mi? Bilmiyoruz. X'in Y işini bitirmeden başka şeyler yapabileceğini biliyoruz. Burada X (bir modül) tıkanmaz. X ve Y iki iş parçacığı mı, iki işlem mi yoksa bir işlem mi? Bilmiyoruz. AMA X ve Y'nin bir iş parçacığı olamayacağından eminiz.
3) senkron: Y cevap vermeden önce X, cevap bekler. Bu, X, Y işini bitirene kadar devam edemeyeceği anlamına gelir. Şimdi diyoruz: X ve Y (iki modül) senkron. X ve Y iki iş parçacığı mı yoksa iki işlem mi, bir iş parçacığı mı yoksa bir işlem mi? Bilmiyoruz.
4) asenkron: Y X cevap vermeden önce, X orada bırakır ve X başka işler yapabilir. X, Y onu arayacak kadar geri gelmeyecek. Şimdi diyoruz: X ve Y (iki modül) asenkron. X ve Y iki iş parçacığı mı, iki işlem mi yoksa bir işlem mi? Bilmiyoruz. AMA X ve Y'nin bir iş parçacığı olamayacağından eminiz.
Lütfen yukarıdaki iki koyu cümleye dikkat edin. 2) 'deki kalın cümle neden iki vaka içerirken, 4)' deki kalın cümle sadece bir vaka içerir? Bu, engellemeyen ve eşzamansız arasındaki farkın anahtarıdır.
İşte engelleme ve senkronize ile ilgili tipik bir örnek:
// thread X
while (true)
{
msg = recv(Y, NON_BLOCKING_FLAG);
if (msg is not empty)
{
break;
}
sleep(2000); // 2 sec
}
// thread Y
// prepare the book for X
send(X, book);
Bu tasarımın engellemediğini görebilirsiniz (çoğu zaman bu döngünün saçma bir şey yaptığını söyleyebilirsiniz, ancak CPU'nun gözünde X çalışıyor, bu da X'in engellemediği anlamına geliyor), X ve Y senkronize çünkü Kitabı Y'den
alana kadar başka şeyler yapmaya devam etmeyin (X döngüden atlayamaz). Normalde bu durumda X engellemeyi çok daha iyi yapın çünkü engellemenin aptalca bir döngü için çok fazla kaynak harcaması. Ancak bu örnek gerçeği anlamanıza yardımcı olmak için iyidir: tıkanmasız asenkron demek değildir.
Dört kelime bizi kolayca karıştırır, hatırlamamız gereken şey, dört kelimenin mimarlık tasarımına hizmet etmesidir. İyi bir mimari tasarlamayı öğrenmek, onları ayırt etmenin tek yoludur.
Örneğin, böyle bir mimari tasarlayabiliriz:
// Module X = Module X1 + Module X2
// Module X1
while (true)
{
msg = recv(many_other_modules, NON_BLOCKING_FLAG);
if (msg is not null)
{
if (msg == "done")
{
break;
}
// create a thread to process msg
}
sleep(2000); // 2 sec
}
// Module X2
broadcast("I got the book from Y");
// Module Y
// prepare the book for X
send(X, book);
Buradaki örnekte şunu söyleyebiliriz:
Gerekirse, X1'de oluşturulan konuları dört kelimeyle de tanımlayabilirsiniz.
Daha da önemlisi: asenkron yerine ne zaman senkron kullanıyoruz? engelleme yerine engellemeyi ne zaman kullanırız?
Nginx neden tıkanmıyor? Apache neden engelleniyor?
İyi bir seçim yapmak için, ihtiyacınızı analiz etmeli ve farklı mimarilerin performansını test etmelisiniz. Çeşitli ihtiyaçlara uygun böyle bir mimari yoktur.
Java 7'de bu soruyu NIO ve NIO.2 bağlamında ele alan asenkron IO, engellememekten bir adım daha ileri düzeydedir. Java NIO engellemeyen çağrılarda, tüm kanallar (SocketChannel, ServerSocketChannel, FileChannel, vb.) Çağrılarak ayarlanır AbstractSelectableChannel.configureBlocking(false)
. Bununla birlikte, bu GÇ çağrıları geri döndükten sonra, tekrar okuma / yazma vb. Gibi kontrolleri kontrol etmeniz gerekecektir.
Örneğin,
while (!isDataEnough()) {
socketchannel.read(inputBuffer);
// do something else and then read again
}
Java 7'deki asenkron api ile bu kontroller daha çok yönlü bir şekilde yapılabilir. İki yoldan biri kullanmaktır CompletionHandler
. Her iki read
aramanın da engellemediğine dikkat edin .
asyncsocket.read(inputBuffer, 60, TimeUnit.SECONDS /* 60 secs for timeout */,
new CompletionHandler<Integer, Object>() {
public void completed(Integer result, Object attachment) {...}
public void failed(Throwable e, Object attachment) {...}
}
}
FileChannel
seçilemez ve engellemeyecek şekilde yapılandırılamaz.
Muhtemelen çok sayıda (ve genellikle birbirini dışlayan) cevaplardan görebileceğiniz gibi, kime sorduğunuza bağlıdır. Bazı arenalarda terimler eş anlamlıdır. Veya her biri iki benzer kavramı ifade edebilir:
Her iki durumda da, amaç, yavaş bir işlemin tamamlanmasını bekleyerek programın engellenmemesine izin vermektir - programın nasıl yanıt vermesi beklenir, tek gerçek fark budur. Hangi terim, programcıdan programcıya, dilden dile veya platformdan platforma da değişir. Veya terimler tamamen farklı kavramları ifade edebilir (diş programlama ile ilgili olarak senkron / asenkron kullanımı gibi).
Üzgünüm, ama küresel olarak doğru olan tek bir doğru cevap olduğuna inanmıyorum.
Bir tıkanmasızdır hemen her türlü veri ile çağrı döndürür mevcuttur: bayt tam sayısının az, talep veya hiç hiçbiri.
Bir asenkron çağrı onun bütün (bütünlüğü) 'de yapılacaktır fakat gelecek bir zamanda tamamlayacak bir transfer ister.
Engelleme yok: Bu işlev yığın üzerindeyken beklemez.
Eşzamansız: Bu çağrı yığından ayrıldıktan sonra işlev çağrısı adına çalışma devam edebilir
Senkron , aynı anda gerçekleşme olarak tanımlanır.
Asenkron , aynı anda olmaması olarak tanımlanır.
İlk karışıklığa neden olan şey budur. Senkron aslında paralel olarak bilinir. Asenkron ardışık olsa da, bunu yapın, sonra yapın.
Şimdi tüm sorun eşzamansız bir davranışı modellemekle ilgilidir, çünkü başlamadan önce bir başkasının yanıtını gerektiren bir işleminiz var. Bu bir koordinasyon problemi, şimdi bu operasyona başlayabileceğinizi nasıl bileceksiniz?
En basit çözüm engelleme olarak bilinir.
Engelleme , başka bir şeyin yapılmasını beklemeyi seçtiğiniz ve ihtiyaç duyduğunuz işleme geçmeden önce size bir yanıt vermenizdir.
Bu yüzden tost üzerine tereyağı koymanız gerekiyorsa ve bu nedenle önce yetiştirilen tostu gerekir. Onları koordine edeceğiniz yol, önce yetiştirilen tostu, sonra da tostu patlayana kadar sonsuza dek tost makinesine bakmanız ve sonra onlara tereyağı koymanızdır.
Bu en basit çözüm ve çok iyi çalışıyor. Operasyonlarla koordinasyon gerektirmeyen başka şeyler yapmanız gerekmedikçe, bunu kullanmamanın gerçek bir nedeni yoktur. Örneğin, bazı yemekler yapmak. Neden tostun patlaması için ekmek kızartma makinesine sürekli bakmak boşta bekliyorsunuz, biraz zaman alacağını bildiğinizde ve bitirirken bütün bir yemeği yıkayabilirsiniz?
Burada sırasıyla engellemeyen ve eşzamansız olarak bilinen diğer iki çözüm devreye girer.
Engellememe , işlemin yapılmasını beklerken ilgisiz başka şeyler yapmayı seçtiğinizde olur. Uygun gördüğünüz gibi yanıtın kullanılabilirliğini kontrol etme.
Yani ekmek kızartma makinesine bakmak yerine. Git ve bütün bir yemeği yıka. Ve sonra tost makinesinin patlayıp atmadığını görmek için ekmek kızartma makinesine bakıyorsunuz. Olmazsa, her yemeğin arasındaki ekmek kızartma makinesini kontrol ederek başka bir bulaşık yıka. Tostların patladığını gördüğünüzde, bulaşıkları yıkamayı bırakıyorsunuz ve bunun yerine tostu alıp üzerine tereyağı sürmeye devam ediyorsunuz.
Tostları sürekli kontrol etmek zorunda kalmak sinir bozucu olabilir, ekmek kızartma makinesinin başka bir odada olduğunu hayal edin. Yemeklerin arasında tostu kontrol etmek için o odaya gidecek zamanınızı boşa harcıyorsunuz.
İşte asenkron geliyor.
Asenkron , işlemin yapılmasını beklerken ilgisiz başka şeyler yapmayı seçtiğiniz zamandır. Bununla birlikte, kontrol etmek yerine, başka bir şeye kontrol etme işini devredersiniz, işlemin kendisi veya bir izleyici olabilirsiniz ve bu şey, yanıt alındığında sizi bilgilendirir ve muhtemelen size müdahale eder, böylece diğer işleme devam edebilirsiniz. Buna ihtiyaç duydu.
Tuhaf bir terminoloji. Tüm bu çözümler bağımlı görevlerin eşzamansız koordinasyonunu yaratmanın yolları olduğu için pek bir anlam ifade etmiyor. Bu yüzden olaylı demeyi tercih ederim.
Bu nedenle, tost makinenizi yükseltmeye karar verirsiniz, böylece tost yapılırken bip sesi çıkarır. Bulaşık yaparken bile sürekli dinliyor olursunuz. Bip sesini duyduğunuzda, hafızanızda, mevcut yemeğinizi yıkar bitirir bitirmez, durup tereyağını tosta koyacaksınız. Ya da mevcut yemeğin yıkanmasını kesmeyi ve tostla hemen ilgilenmeyi seçebilirsiniz.
Bip sesini duymakta zorlanıyorsanız, eşinizin tost makinesini sizin için izlemesini ve tostun ne zaman hazır olduğunu size söyletmesini sağlayabilirsiniz. Eşiniz, ekmek kızartma makinesini izleme ve hazır olduklarında size söyleme görevini koordine etmek için yukarıdaki üç stratejiden herhangi birini seçebilir.
Son bir notta, engellemeyen ve zaman uyumsuz (veya olayı aramayı tercih ettiğim) beklerken başka şeyler yapmanıza izin verirken, sizin de sahip olmadığınızı anlamak iyidir. Başka bir şey yapmadan, engellemeyen bir aramanın durumunu sürekli kontrol etmeyi seçebilirsiniz. Bu genellikle engellemekten daha kötüdür (tost makinesine bakmak, sonra uzakta, sonra bitene kadar geri dönmek gibi), bu nedenle birçok engelleme olmayan API, engelleme moduna geçmenizi sağlar. Olay için, size bildirilene kadar boşta bekleyebilirsiniz. Bu durumda dezavantajı, bildirimin eklenmesinin başlaması karmaşık ve maliyetli olabilir. Bip işlevine sahip yeni bir ekmek kızartma makinesi satın almanız veya partnerinizi sizin için izlemeye ikna etmeniz gerekiyordu.
Ve bir şey daha, üçünün de sağladığı ticaretin farkına varmanız gerekir. Biri açıkça diğerlerinden daha iyi değil. Örneğimi düşün. Ekmek kızartma makineniz çok hızlıysa, bir bulaşık yıkamak için zamanınız olmaz, hatta yıkamayı bile başaramazsınız, ekmek kızartma makineniz bu kadar hızlıdır. Bu durumda başka bir şeye başlamak sadece zaman ve çaba kaybıdır. Engelleme yapacak. Benzer şekilde, bir bulaşık yıkamak kızartma işleminden 10 kat daha uzun sürecektir. Kendinize daha neler yapılması gerektiğini sormalısınız. Tost o zamana kadar soğuyabilir ve sertleşebilir, buna değmez, engelleme de yapar. Ya da beklerken yapılacak daha hızlı şeyleri seçmelisiniz. Daha açık bir şekilde var, ama cevabım zaten çok uzun, benim açımdan, tüm bunları ve buna değip değmeyeceğine ve
Düzenle:
Bu zaten uzun olmasına rağmen, tam olmasını da istiyorum, bu yüzden iki nokta daha ekleyeceğim.
1) Ayrıca çoğullamalı olarak bilinen dördüncü bir model de vardır . Bu, bir görevi beklerken, diğerini başlatırken ve her ikisini de beklerken, bir tane daha başlatırsınız, ve böylece, birçok görev başlayana kadar ve sonra boşta beklersiniz, ancak onlar. Böylece, herhangi bir şey yapılır yapılmaz, yanıtını ele almaya devam edebilir ve daha sonra diğerlerini beklemeye geri dönebilirsiniz. Çoğullama olarak bilinir, çünkü beklerken her bir işi birbiri ardına kontrol etmelisiniz. Normal engellemenin üstünde bir uzantı.
Örneğimizde, ekmek kızartma makinesini, sonra bulaşık makinesini, sonra mikrodalga fırını vb. Başlatmak gibi bir şey. Ekmek kızartma makinesinin yapılıp yapılmadığını kontrol edeceğiniz yerde, eğer değilse, bulaşık makinesini, mikrodalga fırını ve tekrar kontrol edersiniz.
2) Büyük bir hata olduğuna inanmama rağmen, senkronize sıklıkla bir seferde bir şey anlamına gelir. Ve bir seferde asenkron birçok şey. Böylece, engelleme ve engellememeyi ifade etmek için senkronize engellemenin ve engellememenin kullanıldığını görürsünüz. Ve asenkronize bloke edici ve bloke edici olmayan, çoğullamalı ve olaylı anlamına gelir.
Oraya nasıl geldiğimizi gerçekten anlamıyorum. Ancak, IO ve Hesaplama söz konusu olduğunda, senkron ve asenkron, genellikle üst üste binmeyen ve üst üste binen olarak bilinen şeyi ifade eder. Yani, eşzamansız, IO ve Computation'ın üst üste bindikleri, yani eşzamanlı olarak gerçekleştiği anlamına gelir. Eşzamanlı olmaları anlamına gelse de, bunlar sırayla gerçekleşir. Eşzamanlı engelleme için, diğer IO veya Hesaplamaya başlamadığınız anlamına gelir, sadece beklemek ve engelleme çağrısını simüle etmekle meşgulsünüz. İnsanların senkronize ve senkronize olmayan bu şekilde yanlış kullanmayı bırakmalarını dilerim. Bu yüzden teşvik etmiyorum.
Aramayı engelleme : Kontrol yalnızca arama tamamlandığında geri döner.
Engellemeyen çağrı: Kontrol hemen geri döner. Daha sonraki işletim sistemi bir şekilde çağrının tamamlandığını bildirir.
Senkron program: Çağrıları engelleme özelliğini kullanan bir program . Arama sırasında donmamak için 2 veya daha fazla iş parçacığı olmalıdır (bu nedenle Eşzamanlı olarak adlandırılır - iş parçacıkları eşzamanlı olarak çalışır).
Eşzamansız program: Engellemeyen çağrıları kullanan bir program . Yalnızca 1 iş parçacığı olabilir ve yine de etkileşimli kalabilir.
Yalnızca yazım açısından farklılık gösterirler. Ne demek istedikleri arasında bir fark yok. Teknik olmak için vurguda farklı olduklarını söyleyebilirsiniz. Engellememe, kontrol akışını ifade eder (engellemez.) Eşzamansız, etkinlik \ verilerinin ne zaman işlendiğini (eşzamanlı değil) ifade eder.
Engelleme modelleri, G / Ç başlatıldığında başlatılan uygulamanın engellenmesini gerektirir. Bu, işleme ve G / Ç'yi aynı anda çakışmanın mümkün olmadığı anlamına gelir. Senkronize engellemeyen model, işleme ve G / Ç çakışmasına izin verir, ancak uygulamanın G / Ç durumunu tekrar eden bir temelde kontrol etmesini gerektirir. Bu işlem, G / Ç tamamlanma bildirimi de dahil olmak üzere, işleme ve G / Ç çakışmasına izin veren eşzamansız bloke olmayan G / Ç bırakır.
Engelleme: ilkel (senkronizasyon veya senkronize olmayan) işlem tamamlandıktan sonra denetim çağrılmaya başlar
Engelleme yok: kontrol çağrıldıktan hemen sonra işleme geri döner