Engellemesiz G / Ç, çok iş parçacıklı engelleyici G / Ç'den gerçekten daha hızlı mı? Nasıl?


119

Web'de G / Ç'yi engelleme ve G / Ç'yi engellememe hakkında bazı teknik ayrıntıları araştırdım ve engellemeyen G / Ç'nin G / Ç'yi engellemekten daha hızlı olacağını belirten birkaç kişi buldum. Örneğin bu belgede .

Engelleyici G / Ç kullanırsam, elbette şu anda engellenen iş parçacığı başka bir şey yapamaz ... Çünkü engellenmiş. Ancak bir iş parçacığı engellenmeye başlar başlamaz, işletim sistemi başka bir iş parçacığına geçebilir ve engellenen iş parçacığı için yapılacak bir şey olana kadar geri dönemez. Sistemde CPU'ya ihtiyaç duyan ve engellenmeyen başka bir iş parçacığı olduğu sürece, olay tabanlı engellemesiz bir yaklaşıma kıyasla daha fazla CPU boşta kalma süresi olmamalıdır, öyle mi?

CPU'nun boşta kaldığı süreyi azaltmanın yanı sıra, bir bilgisayarın belirli bir zaman diliminde gerçekleştirebileceği görevlerin sayısını artırmak için bir seçenek daha görüyorum: İş parçacığı değiştirmenin getirdiği ek yükü azaltın. Ama bu nasıl yapılabilir? Üst kısım ölçülebilir etkiler gösterecek kadar büyük mü? İşte nasıl çalıştığını nasıl hayal edebileceğime dair bir fikir:

  1. Bir dosyanın içeriğini yüklemek için, bir uygulama bu görevi olay tabanlı bir G / Ç çerçevesine devreder ve bir dosya adı ile birlikte bir geri arama işlevi iletir.
  2. Olay çerçevesi, dosyayı doğrudan belleğe yazmak için sabit diskin bir DMA denetleyicisini programlayan işletim sistemine delege eder.
  3. Olay çerçevesi daha fazla kodun çalışmasına izin verir.
  4. Diskten belleğe kopyalama tamamlandığında, DMA denetleyicisi bir kesintiye neden olur.
  5. İşletim sisteminin kesme işleyicisi, olay tabanlı g / ç çerçevesini belleğe tamamen yüklenen dosya hakkında bilgilendirir. Bunu nasıl yapıyor? Sinyal mi kullanıyorsunuz?
  6. O anda olay g / ç çerçevesinde çalıştırılan kod sona erer.
  7. Olay tabanlı G / Ç çerçevesi kuyruğunu kontrol eder ve işletim sisteminin 5. adımdaki mesajını görür ve 1. adımda aldığı geri aramayı yürütür.

Böyle mi çalışıyor? Olmazsa nasıl çalışır? Bu, olay sisteminin yığına açıkça dokunma ihtiyacı olmadan çalışabileceği anlamına gelir (örneğin, diziyi yedeklemesi ve iş parçacığı arasında geçiş yaparken başka bir iş parçacığının yığınını belleğe kopyalaması gereken gerçek bir zamanlayıcı gibi)? Bu gerçekte ne kadar zaman kazandırır? Daha fazlası var mı?


5
kısa cevap: daha çok bağlantı başına bir iş parçacığına sahip olmanın ek yükü ile ilgili. non-blocking io, bir kişinin bağlantı başına bir iş parçacığından kaçınmasını sağlar.
Dan D.

10
Bağlantıların olduğu kadar iş parçacığı oluşturamayacağınız bir sistemde GÇ'yi engellemek pahalıdır. JVM'de binlerce iş parçacığı oluşturabilirsiniz, ancak ya 100.000'den fazla bağlantınız varsa? Yani asenkron bir çözüme bağlı kalmalısınız. Ancak, 100.000 iş parçacığına sahip olmanın sorun olmadığı Go / Erlang / Rust'ta olduğu gibi iş parçacıklarının pahalı olmadığı diller (örneğin yeşil ipler) vardır. İş parçacığı sayısı büyük olabildiğinde, GÇ'yi engellemenin daha hızlı yanıt süreleri sağladığına inanıyorum. Ancak bu, uzmanlara bunun gerçekte doğru olup olmadığını sormam gereken bir şey.
OlliP

@OliverPlow, ben de öyle düşünüyorum, çünkü IO'yu bloke etmek genellikle görev kuyruklarını vb. Kullanarak kendimiz yapmak yerine sistemin "paralel yönetimi" halletmesine izin vermemiz anlamına geliyor .
Pacerier

1
@DanD., Peki ya iş parçacığına sahip olmanın ek yükü, engellemeyen IO'yu performa eden ek yüke eşitse? (genellikle yeşil ipler için doğrudur)
Pacerier

"yığının kopyalanması" gerçekleşmez. Farklı iş parçacığı yığınları farklı adreslere sahiptir. Her iş parçacığı, diğer kayıtlarla birlikte kendi yığın işaretçisine sahiptir. Bir bağlam anahtarı yalnızca mimari durumu (tüm kayıtlar dahil) kaydeder / geri yükler, ancak belleği kaydetmez. Aynı süreçteki evreler arasında, çekirdeğin sayfa tablolarını değiştirmesine bile gerek yoktur.
Peter Cordes

Yanıtlar:


44

Engellemesiz veya asenkron G / Ç'nin en büyük avantajı, iş parçacığınızın paralel olarak çalışmaya devam edebilmesidir. Elbette bunu ek bir iplik kullanarak da elde edebilirsiniz. En iyi genel (sistem) performansı için belirttiğiniz gibi, sanırım eşzamansız G / Ç kullanmak ve birden çok iş parçacığı kullanmak daha iyi olurdu (dolayısıyla iş parçacığı değiştirmeyi azaltın).

Paralel bağlanmış 1000 istemciyi idare edecek bir ağ sunucusu programının olası uygulamalarına bakalım:

  1. Bağlantı başına bir iş parçacığı (G / Ç'yi engelleyebilir, ancak G / Ç'yi engellemeyebilir).
    Her iş parçacığı bellek kaynakları gerektirir (ayrıca çekirdek belleği!), Bu bir dezavantajdır. Ve her ek iş parçacığı, zamanlayıcı için daha fazla çalışma anlamına gelir.
  2. Tüm bağlantılar için tek iş parçacığı.
    Daha az iş parçacığına sahip olduğumuz için bu sistemden yük alır. Ama aynı zamanda makinenizin tam performansını kullanmanızı da engeller, çünkü sonunda bir işlemciyi% 100'e çıkarabilir ve diğer tüm işlemcilerin boşta kalmasına izin verebilirsiniz.
  3. Her iş parçacığının bazı bağlantıları ele aldığı birkaç iş parçacığı.
    Bu, daha az iş parçacığı olduğu için sistemden yükü alır. Ve mevcut tüm işlemcileri kullanabilir. Windows'ta bu yaklaşım Thread Pool API tarafından desteklenmektedir .

Elbette daha fazla iş parçacığına sahip olmak başlı başına bir sorun değildir. Fark etmiş olabileceğiniz gibi, oldukça fazla sayıda bağlantı / iş parçacığı seçtim. Sadece bir düzine iş parçacığından bahsediyorsak, olası üç uygulama arasında herhangi bir fark göreceğinizden şüpheliyim (Raymond Chen de MSDN blog gönderisinde önerdiği şey, Windows'un işlem başına 2000 iş parçacığı sınırı var mı? ).

Arabelleğe alınmamış dosya G / Ç kullanan Windows'ta , yazma işlemlerinin sayfa boyutunun katı olan bir boyutta olması gerektiği anlamına gelir. Test etmedim, ancak bu, arabelleğe alınmış eşzamanlı ve eşzamansız yazma işlemleri için yazma performansını olumlu yönde etkileyebilir gibi görünüyor.

Açıkladığınız 1'den 7'ye kadar olan adımlar, nasıl çalıştığı hakkında iyi bir fikir verir. Windows'ta işletim sistemi (eşzamanlı olmayan bir I / O tamamlanmasından hakkında bilgilendirecektir WriteFileile OVERLAPPEDbir etkinlik ya da geri arama kullanarak yapısı). Geri arama işlevleri, örneğin kod çağrılarınız şu WaitForMultipleObjectsExşekilde bAlertableayarlandığında çağrılır:true .

Web'de biraz daha okumak:


Web açısından bakıldığında, ortak bilgi (İnternet, uzmanların yorumları) maks. istek iş parçacığı sayısı, bellek artışı ve bağlam değiştirme süresi nedeniyle GÇ'yi engellemede (isteklerin işlenmesini daha da yavaşlatmada) kötü bir şeydir, ancak Async GÇ işi başka bir iş parçacığına ertelerken aynı şeyi yapmıyor mu? Evet, şimdi daha fazla istek sunabilirsiniz, ancak arka planda aynı sayıda iş parçacığı var .. Bunun gerçek faydası nedir?
JavierJ

1
@JavierJ Eğer n iş parçacığı eşzamansız dosya IO yaparsa, bir engelleme dosyası GÇ'si yapmak için başka bir n iş parçacığı oluşturulacağına inanıyorsunuz? Bu doğru değil. İşletim sistemi eşzamansız dosya IO desteğine sahiptir ve IO'nun tamamlanmasını beklerken engellenmesi gerekmez. IO isteklerini sıraya koyabilir ve bir donanım (örn. DMA) kesintisi meydana gelirse, isteği tamamlandı olarak işaretleyebilir ve arayanın iş parçacığını işaret eden bir olay ayarlayabilir. Fazladan bir iş parçacığı gerekse bile, işletim sistemi bu iş parçacığını birden çok iş parçacığından birden çok GÇ isteği için kullanabilir.
Werner Henze

Teşekkürler, işletim sistemi eşzamansız dosya IO desteğini dahil etmek mantıklıdır, ancak bunun gerçek bir uygulaması için kod yazdığımda (web açısından bakıldığında), Java Servlet 3.0 NIO ile söyleyin hala istek için bir iş parçacığı ve bir arka plan iş parçacığı görüyorum ( zaman uyumsuz) bir dosyayı, veritabanını veya her neyse okumak için döngü.
JavierJ

1
@piyushGoyal Cevabımı yeniden yazdım. Umarım şimdi daha nettir.
Werner Henze

1
Eşzamansız dosya G / Ç kullanan Windows'ta, yazma işlemlerinin sayfa boyutunun katı olan bir boyutta olması gerektiği anlamına gelir. - hayır, öyle değil. Tamponlanmamış bir G / Ç düşünüyorsunuz. (Genellikle birlikte kullanılırlar, ancak olmaları gerekmez.)
Harry Johnston

29

G / Ç, sabit sürücülerden veri okuma ve yazma, ağ kaynaklarına erişim, web hizmetlerini arama veya veritabanlarından veri alma gibi çok sayıda işlem içerir. Platforma ve işlemin türüne bağlı olarak, asenkron G / Ç genellikle işlemi gerçekleştirmek için herhangi bir donanımdan veya düşük seviyeli sistem desteğinden yararlanacaktır. Bu, CPU üzerinde mümkün olan en az etkiyle gerçekleştirileceği anlamına gelir.

Uygulama düzeyinde, eşzamansız G / Ç, iş parçacıklarının G / Ç işlemlerinin tamamlanmasını beklemek zorunda kalmasını önler. Eşzamansız bir G / Ç işlemi başlatılır başlatılmaz, başlatıldığı iş parçacığını serbest bırakır ve bir geri arama kaydedilir. İşlem tamamlandığında, geri arama mevcut ilk iş parçacığında yürütülmek üzere kuyruğa alınır.

G / Ç işlemi eşzamanlı olarak yürütülürse, işlem tamamlanana kadar çalışan iş parçacığının hiçbir şey yapmamasını sağlar. Çalışma zamanı, G / Ç işleminin ne zaman tamamlandığını bilmez, bu nedenle, bekleme iş parçacığına periyodik olarak bir miktar CPU süresi, aksi takdirde gerçekleştirilecek gerçek CPU bağlantılı işlemlere sahip diğer iş parçacıkları tarafından kullanılabilecek CPU zamanı sağlar.

Dolayısıyla, @ user1629468'de belirtildiği gibi, eşzamansız G / Ç daha iyi performans sağlamaz, aksine daha iyi ölçeklenebilirlik sağlar. Bu, web uygulamalarında olduğu gibi, sınırlı sayıda iş parçacığı olan bağlamlarda çalışırken açıktır. Web uygulaması genellikle her bir isteğe iş parçacığı atadıkları bir iş parçacığı havuzu kullanır. Uzun süren G / Ç işlemlerinde istekler engellenirse, web havuzunun tükenmesi ve web uygulamasının donması veya yanıt vermesinin yavaşlaması riski vardır.

Çok hızlı G / Ç işlemleriyle uğraşırken asenkron G / Ç'nin en iyi seçenek olmadığını fark ettiğim bir şey var. Bu durumda, G / Ç işleminin tamamlanmasını beklerken bir iş parçacığını meşgul tutmamanın yararı çok önemli değildir ve işlemin bir iş parçacığı üzerinde başlatılması ve diğerinde tamamlanması olgusu, genel yürütmeye bir ek yük getirir.

Sen Geçenlerde mulithread asenkron I konu / Ç vs üzerinde yapmış daha ayrıntılı araştırma okuyabilir burada .


Uzaktaki aygıtın olabileceği veya olmayabileceği durumlarda, tamamlanması beklenen G / Ç işlemleri ile gerçekleşmeyebilecek şeyler arasında bir ayrım yapmaya değip değmeyeceğini merak ediyorum [ör. "Seri bağlantı noktasına gelen sonraki karakteri al" bir şey gönder]. Bir G / Ç işleminin makul bir süre içinde tamamlanması bekleniyorsa, ilgili kaynakların temizlenmesi işlem tamamlanana kadar ertelenebilir. Ancak operasyon hiçbir zaman tamamlanamazsa, böyle bir gecikme mantıksız olacaktır.
supercat

@supercat tarif ettiğiniz senaryo, daha düşük seviyeli uygulamalarda ve kitaplıklarda kullanılmaktadır. Sunucular, gelen bağlantıları sürekli bekledikleri için buna güveniyorlar. Yukarıda açıklandığı gibi zaman uyumsuz G / Ç bu senaryoya uymaz çünkü belirli bir işlemi başlatmaya ve tamamlanması için bir geri aramayı kaydetmeye dayanır. Açıklamanız durumunda, bir sistem olayına bir geri arama kaydetmeniz ve her bildirimi işlemeniz gerekir. İşlem yapmak yerine sürekli olarak girdiyi işliyorsunuz. Dediğim gibi, bu genellikle uygulamalarınızda neredeyse hiçbir zaman düşük seviyede yapılır.
Florin Dumitrescu

Model, çeşitli donanım türleriyle gelen uygulamalarda oldukça yaygındır. Seri bağlantı noktaları eskisi kadar yaygın değildir, ancak seri bağlantı noktalarını taklit eden USB yongaları, özel donanım tasarımında oldukça popülerdir. Bu tür şeylerden gelen karakterler uygulama düzeyinde ele alınır, çünkü işletim sistemi bir dizi giriş karakterinin, örneğin bir nakit çekmecesinin açıldığı ve bir yere bir bildirim gönderilmesi gerektiği anlamına geldiğini bilmesinin hiçbir yolu olmayacaktır.
supercat

GÇ'yi engellemenin CPU maliyetiyle ilgili kısmın doğru olduğunu düşünmüyorum: engelleme durumundayken, GÇ'yi engelleyen bir iş parçacığı işletim sistemi tarafından beklemeye alınır ve GÇ tamamen tamamlanana kadar CPU sürelerine mal olmaz, ancak bundan sonra OS (kesintilerle bildirir) bloke edilen iş parçacığını devam ettirir. Açıkladığınız şey (uzun yoklama ile meşgul bekleme), neredeyse her çalışma zamanı / derleyicide GÇ engellemenin nasıl uygulandığı değildir.
Lifu Huang

4

AIO kullanmanın ana nedeni ölçeklenebilirliktir. Birkaç konu bağlamında incelendiğinde, faydalar açık değildir. Ancak sistem 1000 iş parçacığına ölçeklendiğinde, AIO çok daha iyi performans sunacaktır. Uyarı, AIO kütüphanesinin daha fazla darboğaz getirmemesi gerektiğidir.


4

Herhangi bir çoklu hesaplama biçimi nedeniyle bir hız artışı olduğunu varsaymak için, birden çok CPU tabanlı görevin aynı anda birden çok bilgi işlem kaynağı (genellikle işlemci çekirdeği) üzerinde yürütüldüğünü ya da tüm görevlerin eşzamanlı kullanımına bağlı olmadığını varsaymalısınız. aynı kaynak - yani, bazı görevler bir sistem alt bileşenine (örneğin disk depolama) bağlı olabilirken, bazı görevler diğerine bağlıdır (bir çevresel aygıttan iletişim alma) ve yine de diğerleri işlemci çekirdeklerinin kullanımını gerektirebilir.

İlk senaryoya genellikle "paralel" programlama adı verilir. İkinci senaryo genellikle "eşzamanlı" veya "eşzamansız" programlama olarak adlandırılır, ancak "eşzamanlı" da bazen yalnızca bir işletim sisteminin birden fazla görevin yürütülmesi gerekip gerekmediğinden bağımsız olarak birden fazla görevin yürütülmesine izin verme durumuna atıfta bulunmak için kullanılır. seri olarak yerleştirin veya paralel yürütmeyi gerçekleştirmek için birden fazla kaynak kullanılabiliyorsa. Bu ikinci durumda, "eşzamanlı" genellikle görev yürütmenin gerçek eşzamanlılığı perspektifinden ziyade, yürütmenin programda yazılma şeklini ifade eder.

Bütün bunlar hakkında üstü kapalı varsayımlarla konuşmak çok kolay. Örneğin, bazıları "Eşzamansız G / Ç, çok iş parçacıklı G / Ç'den daha hızlı olacak" gibi bir iddiada bulunmakta hızlıdır. Bu iddia birkaç nedenden dolayı şüphelidir. Birincisi, verilen bazı eşzamansız G / Ç çerçevesinin tam olarak çoklu iş parçacığı ile uygulanması söz konusu olabilir, bu durumda bunlar aynıdır ve bir kavramın diğerinden "daha hızlı" olduğunu söylemek mantıklı değildir. .

İkinci olarak, eşzamansız bir çerçevenin tek iş parçacıklı bir uygulaması olduğu durumda bile (tek iş parçacıklı bir olay döngüsü gibi), yine de bu döngünün ne yaptığı hakkında bir varsayımda bulunmalısınız. Örneğin, tek iş parçacıklı bir olay döngüsüyle yapabileceğiniz aptalca bir şey, eşzamansız olarak iki farklı tamamen CPU'ya bağlı görevi tamamlama isteğidir. Bunu yalnızca idealleştirilmiş tek işlemci çekirdeği olan bir makinede yaptıysanız (modern donanım optimizasyonlarını göz ardı ederek), bu görevi "eşzamansız olarak" gerçekleştirmek, onu iki bağımsız olarak yönetilen iş parçacığı veya yalnızca tek bir işlemle gerçekleştirmekten gerçekten farklı bir performans göstermez - - fark, iş parçacığı bağlamı değiştirme veya işletim sistemi çizelgesi optimizasyonlarından kaynaklanabilir, ancak her iki görev de CPU'ya gidiyorsa, her iki durumda da benzer olacaktır.

Karşılaşabileceğiniz pek çok olağandışı veya aptalca köşe vakasını hayal etmek yararlıdır.

"Eşzamansız" eşzamanlı olmak zorunda değildir, örneğin yukarıdaki gibi: tam olarak bir işlemci çekirdeğine sahip bir makinede iki CPU'ya bağlı görevi "eşzamansız olarak" yürütürsünüz.

Çok iş parçacıklı yürütme eşzamanlı olmak zorunda değildir: tek bir işlemci çekirdeği olan bir makinede iki iş parçacığı oluşturur veya iki iş parçacığının diğer türden kıt kaynakları elde etmesini istersiniz (örneğin, yalnızca birini kurabilen bir ağ veritabanı hayal edin) bir seferde bağlantı). İş parçacığının yürütülmesi aralıklı olabilir, ancak işletim sistemi zamanlayıcısı uygun görür, ancak toplam çalışma süreleri tek bir çekirdekte azaltılamaz (ve iş parçacığı bağlamı değiştirmesinden artırılacaktır) (veya daha genel olarak, eğer mevcut olandan daha fazla iş parçacığı oluşturursanız) onları çalıştırmak için çekirdekler veya kaynağın sürdürebileceğinden daha fazla kaynak isteyen iş parçacığı var). Aynı şey çoklu işleme için de geçerlidir.

Bu nedenle, ne asenkron G / Ç ne de çoklu iş parçacığı çalışma süresi açısından herhangi bir performans kazancı sunmak zorunda değildir. Hatta işleri yavaşlatabilirler.

Bununla birlikte, hem uzak bir veritabanı gibi ağa bağlı bir kaynaktan veri almak için bir ağ çağrısı yapan hem de bazı yerel CPU'ya bağlı hesaplamalar yapan belirli bir program gibi belirli bir kullanım durumu tanımlarsanız, donanım hakkında belirli bir varsayım verildiğinde iki yöntem arasındaki performans farklılıkları.

Sorulacak sorular: Kaç tane hesaplama adımını gerçekleştirmem gerekiyor ve bunları gerçekleştirmek için kaç bağımsız kaynak sistemi var? Bağımsız sistem alt bileşenlerinin kullanılmasını gerektiren ve bunu aynı anda yapmaktan yararlanabilecek hesaplama adımlarının alt kümeleri var mı? Kaç işlemci çekirdeğim var ve görevleri ayrı çekirdeklerde tamamlamak için birden fazla işlemci veya iş parçacığı kullanmanın ek yükü nedir?

Görevleriniz büyük ölçüde bağımsız alt sistemlere dayanıyorsa, zaman uyumsuz bir çözüm iyi olabilir. İşlenmesi gereken iş parçacığı sayısı büyükse, böylece bağlam değiştirme işletim sistemi için önemsiz hale gelirse, tek iş parçacıklı eşzamansız bir çözüm daha iyi olabilir.

Görevler aynı kaynakla bağlandığında (örneğin, aynı ağa veya yerel kaynağa eşzamanlı olarak erişmek için birden fazla ihtiyaç), o zaman çoklu iş parçacığı muhtemelen tatmin edici olmayan ek yük getirecektir ve tek iş parçacıklı eşzamansızlık böyle bir kaynakta daha az ek yük getirebilir. sınırlı durum da bir hızlanma üretemez. Böyle bir durumda, tek seçenek (hızlandırma istiyorsanız) o kaynağın birden çok kopyasını kullanılabilir hale getirmektir (örneğin, kıt kaynak CPU ise birden fazla işlemci çekirdeği; kıt kaynak varsa daha fazla eşzamanlı bağlantıları destekleyen daha iyi bir veritabanı) bağlantısı sınırlı bir veritabanıdır, vb.).

Koymak için başka bir yoludur: işletim sistemi iki görevler için tek kaynak kullanımını serpiştirmek için izin olamaz hızlı sadece bir görev kullanımını diğer bekler, daha sonra seri ikinci görev bitirmek izin verirken kaynak icar daha olacak. Ayrıca, serpiştirmenin programlayıcı maliyeti, herhangi bir gerçek durumda aslında bir yavaşlama yarattığı anlamına gelir. Aralıklı kullanımın CPU, bir ağ kaynağı, bir bellek kaynağı, bir çevresel aygıt veya herhangi bir başka sistem kaynağından meydana gelmesi önemli değildir.


2

Engellemeyen G / Ç'nin olası bir uygulaması, G / Ç'yi engelleyen ve bazı geri arama mekanizmaları aracılığıyla G / Ç'yi oluşturan iş parçacığını bilgilendiren bir arka plan iş parçacığı havuzu ile tam olarak söylediğiniz şeydir. Aslında, glibc'deki AIO modülü bu şekilde çalışır. Buraya ilgili bazı belirsiz ayrıntılar.

Bu oldukça taşınabilir olan iyi bir çözüm olsa da (iş parçacığına sahip olduğunuz sürece), işletim sistemi tipik olarak engellemeyen G / Ç'ye daha verimli hizmet verebilir. Bu Wikipedia makalesi , iş parçacığı havuzunun yanı sıra olası uygulamaları listeler.


2

Şu anda protothreads kullanarak gömülü bir platformda zaman uyumsuz io uygulama sürecindeyim. Engellemesiz io, 16000 fps ve 160 fps'de çalıştırma arasındaki farkı yaratır. Engellemesiz io'nun en büyük yararı, kodunuzu donanım işini yaparken başka şeyler yapacak şekilde yapılandırabilmenizdir. Cihazların başlatılması bile paralel olarak yapılabilir.

kırlangıç


1

Düğümde, birden çok iş parçacığı başlatılıyor, ancak bu, C ++ çalışma zamanında bir katmandır.

"Yani, Evet NodeJS tek iş parçacıklı, ancak bu yarı gerçek, aslında olay odaklı ve arka plan çalışanlarıyla tek iş parçacıklı. Ana olay döngüsü tek iş parçacıklı ancak G / Ç çalışmalarının çoğu ayrı iş parçacıkları üzerinde çalışıyor, çünkü Node.js'deki G / Ç API'leri, olay döngüsünü barındırmak için tasarım gereği eşzamansız / engellemesizdir. "

https://codeburst.io/how-node-js-single-thread-mechanism-work-understanding-event-loop-in-nodejs-230f7440b0ea

"Node.js engelleyici değildir, bu da tüm işlevlerin (geri aramaların) olay döngüsüne delege edildiği ve farklı evreler tarafından yürütüldüğü (veya yürütülebildiği) anlamına gelir. Bu, Node.js çalışma zamanı tarafından işlenir."

https://itnext.io/multi-threading-and-multi-process-in-node-js-ffa5bb5cde98 

"Düğüm daha hızlı çünkü engelleyici değil ..." açıklaması biraz pazarlama ve bu harika bir soru. Verimli ve ölçeklenebilir, ancak tam olarak tek iş parçacıklı değil.


0

Bildiğim kadarıyla gelişme, Eşzamansız G / Ç'nin sözde G / Ç tamamlama bağlantı noktalarını ( sadece açıklığa kavuşturmak için MS Sisteminden bahsediyorum) kullanmasıdır . Zaman uyumsuz çağrıyı kullanarak çerçeve, bu tür mimariden otomatik olarak yararlanır ve bunun, standart iş parçacığı mekanizmasından çok daha verimli olması beklenir. Kişisel bir deneyim olarak söyleyebilirim ki, konuları engellemek yerine AsyncCalls'ı tercih ederseniz, uygulamanızı daha duyarlı hissedersiniz.


0

Eşzamansız G / Ç'nin çalışmadığına dair bir karşı örnek vereyim. Aşağıdaki boost :: asio kullanımına benzer bir proxy yazıyorum. https://github.com/ArashPartow/proxy/blob/master/tcpproxy_server.cpp

Ancak benim durumumun senaryosu, gelen (istemci tarafından) mesajlar hızlı iken giden (sunucu tarafına) bir oturum için yavaş, gelen hıza ayak uydurmak veya toplam proxy verimini en üst düzeye çıkarmak için kullanmalıyız tek bağlantı altında birden çok oturum.

Böylece bu eşzamansız G / Ç çerçevesi artık çalışmıyor. Her iş parçacığına bir oturum atayarak sunucuya göndermek için bir iş parçacığı havuzuna ihtiyacımız var.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.