Ne zaman yüzbinlerce konuya ihtiyacınız olacak?


31

Erlang, Go ve Rust, hepsi bir şekilde veya ucuz "thread" / coroutines ile eşzamanlı programlamayı desteklediklerini iddia ediyorlar. Git SSS devletler:

Aynı adres alanında yüz binlerce goroutin oluşturmak pratiktir.

Pas Eğitimi diyor ki:

Görevleri geleneksel iş parçacıklarından önemli ölçüde daha ucuz olduğu için, Rust tipik bir 32 bit sistemde yüz binlerce eşzamanlı görev oluşturabilir.

Erlang'ın belgeleri şöyle diyor:

Varsayılan 233 kelimelik yığın büyüklüğü, yüz binlerce, hatta milyonlarca işlemden oluşan Erlang sistemlerini desteklemek için oldukça tutucudur.

Sorum şu: ne tür bir uygulama çok eşzamanlı yürütme işlemi gerektiriyor? Yalnızca en yoğun web sunucusu binlerce eşzamanlı ziyaretçiyi bile alır. Patron-işçi / iş gönderme tipi uygulamaları Yazdığım iş parçacığı / işlem sayısı, fiziksel çekirdek sayısından çok daha büyük olduğunda isabet azalan sonuçlarla sonuçlanır. Sayısal uygulamalar için mantıklı gelebilir, ancak gerçekte çoğu insan bu yeni nesil dilleri için değil, Fortran / C / C ++ dilinde yazılmış üçüncü taraf kütüphanelerine paralelliğe sahiptir.


5
Sanırım kafanızın kaynağı şudur: Bu mikrotikler / görevler / etc, öncelikle konuştuğunuz işletim sistemi dişlileri / süreçlerinin yerine geçme amacı taşımamaktadır, bunlar aynı zamanda, kolayca paralelleştirilebilen büyük bir sayıdaki çatırtı yığınını bölmek için kullanılmayacaklardır. birkaç çekirdek arasında (doğru şekilde belirttiğiniz gibi, bu amaç için 4 çekirdek üzerinde 100k ipliğin olduğu hiçbir nokta yoktur).
us2012

1
Öyleyse ne anlama geliyorlar? Belki bir safım ama koroinler / etc tanıtmanın tek bir yürütme iş parçacığı programını basitleştireceği bir durumla hiç karşılaşmadım. Ve Linux ile yüzlerce veya binlerce ter atmadan başlatabileceğim süreçlerle "düşük" eşzamanlılık seviyelerine ulaşmayı başardım.
kullanıcı39019

Bu kadar çok işin gerçekten işe yaraması çok mantıklı olmaz. Bu, bir şeylerin gerçekleşmesini beklerken çoğunlukla engellenen çok sayıda göreve sahip olamayacağınız anlamına gelmez.
Loren Pechtel

5
Görev temelli eşzamansız - iş parçacığı temelli eşzamansızlık fikri, kullanıcı kodunun, bu görevleri yapan işçileri yönetmek yerine , yapılması gereken işlere odaklanması gerektiğini söylemektir . Bir iş parçacığını işe aldığınız bir işçi olarak düşünün; Bir çalışanı işe almak pahalıdır ve yaparsanız, zamanın% 100'ünün mümkün olduğu kadar çok iş üzerinde çalışmasını istersiniz. Çok sayıda sistem yüzlerce veya binlerce beklemede olan göreve sahip olarak nitelendirilebilir, ancak yüzlerce veya binlerce çalışana ihtiyaç duymazsınız.
Eric Lippert

@ EricLippert'in yorumuna devam edersek, yüz binlerce görevin olabileceği çeşitli durumlar vardır. Örnek 1 - görüntü işleme gibi veri paralel bir görevin ayrıştırılması. Örnek 2: yüzlerce müşteriyi destekleyen ve her biri istediği zaman komut verebilecek bir sunucu. Her görev kendi "hafif yürütme bağlamına" gereksinim duyardı - hangi durumda olduğunu (iletişim protokolleri) ve şu anda yürüttüğü komutu hatırlama yeteneği ve başka bir şey gerektirmezdi. Her biri sığ bir çağrı yığınına sahip olduğu sürece hafif bir ağırlık mümkündür.
rwong,

Yanıtlar:


19

Tek kullanımlık durum - web soketleri:
web soketleri basit taleplere kıyasla uzun ömürlü olduğu için, yoğun bir sunucuda çok sayıda web bağlantısı zamanla birikecektir. mikrotizler size iyi bir kavramsal modelleme ve aynı zamanda nispeten kolay bir uygulama sunar.

daha genel olarak, çok sayıda az ya da çok özerk birimin belirli olayların gerçekleşmesini beklediği durumlar, iyi kullanım durumları olmalıdır.


15

Erlang'ın aslında ne yapmak için tasarlandığını, telekomünikasyonı yönetmek olduğunu düşünmek yardımcı olabilir. Yönlendirme, anahtarlama, sensör toplama / toplama vb.

Bunu web dünyasına getirin - Twitter gibi bir sistemi düşünün . Sistem muhtemelen web sayfalarını oluşturmak için mikro ipler kullanmaz, ancak bunları tweet toplama / önbelleğe alma / dağıtımında kullanabilir.

Bu makale daha fazla yardımcı olabilir.


11

Değişkenleri değiştirme izniniz bulunmayan bir dilde, durumu korumanın basit davranışı ayrı bir yürütme bağlamı gerektirir (çoğu insan bir iş parçacığı ve Erlang bir işlem çağırır). Temel olarak, her şey bir işçidir.

Bir sayacı koruyan bu Erlang işlevini düşünün:

counter(Value) ->
    receive                               % Sit idle until a message is received
        increment -> counter(Value + 1);  % Restart with incremented value
        decrement -> counter(Value - 1);  % Restart with decremented value
        speak     ->
            io:fwrite("~B~n", [Value]),
            counter(Value);               % Restart with unaltered value
        _         -> counter(Value)       % Anything else?  Do nothing.
    end.

C ++ veya Java gibi geleneksel bir OO dilinde, bunu özel bir sınıf üyesine sahip bir sınıf, durumunu almak veya değiştirmek için ortak yöntemler ve her bir sayaç için bir hazır nesne kullanarak elde edersiniz. Erlang, somutlaştırılmış nesnenin nosyonunu bir işlemle, mesajlarla metot kavramını ve durumun bakımını kuyruk durum çağrılarıyla değiştirir ; işlevi, yeni durumu hangi değerlerle olursa olsun yeniden başlatır . Bu modeldeki gizli yarar - ve Erlang’ın en büyük nedeni - dilin bir mesaj kuyruğunu kullanarak sayaç değerine erişimi otomatik olarak seri hale getirmesi ve eşzamanlı kodun yüksek derecede güvenlikle uygulanmasını çok kolay hale getirmesidir. .

Muhtemelen, bağlamsal anahtarların pahalı olduğu fikrine alışkınsınızdır, bu hala ana işletim sistemi perspektifinden doğrudur. Erlang çalışma zamanının kendisi ayarlanmış küçük bir işletim sistemidir, bu nedenle kendi işlemleri arasında geçiş yapmak hızlı ve verimlidir; ancak, bağlamsal anahtarların sayısını korurken işletim sisteminin yaptığı en aza indirgenir. Bu nedenle, binlerce sürece sahip olmak sorun değil ve teşvik edilir.


1
Son uygulamanız counter/1küçük harf c kullanmalıdır;) Düzeltmeye çalıştım, ancak StackExchange 1 karakterli düzenlemeleri sevmiyor.
d11wtq

4

Sorum şu: ne tür bir uygulama çok eşzamanlı yürütme işlemi gerektiriyor?

1) Bir dilin "ölçeklendirilmesi" gerçeği, işler yoldan daha karmaşıklaştıkça bu dili atmanız gerekme olasılığının düşük olduğu anlamına gelir. (Buna "Bütün Ürün" kavramı denir.) Birçok kişi bu nedenle Nginx için Apache'yi kazıyor. İplik ekinin uyguladığı "zor sınırın" yakınında bir yerdeyseniz, korkarsınız ve onu geçmenin yollarını düşünmeye başlarsınız. Web siteleri ne kadar trafik alacaklarını asla tahmin edemezler; bu nedenle, ölçeklendirilebilir hale getirmek için biraz zaman harcamak mantıklıdır.

2) İstek başına bir goroutine sadece başlangıç. Goroutinleri dahili olarak kullanmak için birçok neden var.

  • 100'ün eşzamanlı isteği ile bir web uygulaması düşünün, ancak her istek 100'ünde arka uç istekleri oluşturur. Açık bir örnek bir arama motoru toplayıcısıdır. Ancak, herhangi bir uygulama ekrandaki her "alan" için goroutinler oluşturabilir, ardından bunları sırayla bağımsız olarak oluşturabilir. Örneğin, Amazon.com'daki her sayfa yalnızca sizin için bir araya getirilmiş 150+ arka uç isteğinden oluşur. Fark etmiyorsunuz çünkü paraleldirler, sıralı değildirler ve her "alan" kendi web servisidir.
  • Güvenilirlik ve gecikmenin en önemli olduğu herhangi bir uygulamayı düşünün. Muhtemelen gelen her bir isteğin birkaç arka uç isteğini reddetmesini ve hangi verileri önce geri verdiğini geri vermesini istiyorsun .
  • Uygulamanızda yapılan herhangi bir "müşteri birleşimini" göz önünde bulundurun. "Her bir öğe için veri al" demek yerine, bir sürü gobinde dönebilirsin. Sorgulamak için bir grup köle DB'niz varsa, sihirli bir şekilde N zamanı daha hızlı gideceksiniz. Eğer yapmazsan, daha yavaş olmayacak.

iş parçacığı / işlem sayısı fiziksel çekirdek sayısından çok daha büyük olduğunda isabet azalan döndürmeler

Bir programı CSP'ye bölmenin tek nedeni performans değildir . Aslında programın anlaşılmasını kolaylaştırabilir ve bazı problemler çok daha az kodla çözülebilir.

Yukarıda verilen slaytlarda olduğu gibi, kodunuzda eşzamanlılık olması sorunu organize etmenin bir yoludur. Goroutinlere sahip olmamak, dilinizde bir Harita / Dictonary / Hash veri yapısına sahip olmamak gibidir. Onsuz geçebilirsiniz. Ancak bir kez elinize geçtikten sonra, her yerde kullanmaya başlarsınız ve programınızı gerçekten kolaylaştırır.

Geçmişte, bu çok iş parçacıklı programlama "kendi yuvarla" anlamına geliyordu. Ancak bu karmaşık ve tehlikeliydi - yarış oluşturmadığınızdan emin olmak için hala çok fazla araç yok. Ve gelecekteki bir koruyucunun hata yapmasını nasıl önlersiniz? Büyük / karmaşık programlara bakarsanız, bu yönde çok fazla kaynak harcadıklarını görürsünüz .

Eşzamanlılık çoğu dilin birinci sınıf bir parçası olmadığından, bugünün programcıları neden kendileri için yararlı olacağı konusunda kör bir noktaya sahiptir. Bu sadece her telefon ve kol saati 1000 çekirdeğe doğru geldiğinde daha belirgin hale gelecektir. Dahili bir yarış dedektörü aracıyla birlikte gidin.


2

Erlang için, bağlantı veya başka bir görev için bir işlem olması yaygındır. Dolayısıyla, bir akışlı ses sunucusunun bağlı kullanıcı başına 1 işlem olabilir.

Erlang VM, bağlam anahtarları çok ucuz hale getirerek binlerce hatta yüz binlerce işlemi işlemek için optimize edilmiştir.


1

Kolaylık. Çok iş parçacıklı programlama yapmaya başladığımda eğlence için yan tarafta çok fazla simülasyon ve oyun geliştirme yapıyordum. Her bir nesne için sadece bir ipi döndürmek ve her birini bir döngüden geçirmektense kendi işini yapmasına izin vermenin büyük kolaylık olduğunu buldum. Kodunuz deterministik olmayan davranışlardan rahatsız değilse ve çarpışmalarınız yoksa, kodlamayı kolaylaştırabilir. Şu anda elimizde mevcut olan güçle, eğer geri dönecek olursam, o kadar çok ayrı nesneyi kaldıracak yeterli işlem gücüne ve belleğe sahip olduğum için birkaç bin ipliğin kolayca döndüğünü hayal edebiliyorum!


1

İletişim için tasarlanan Erlang için basit bir örnek: ağ paketlerinin aktarılması. Bir http isteğinde bulunduğunuzda binlerce TCP / IP paketiniz olabilir. Buna herkesin aynı anda bağlandığını ve kullanım durumunuzu da eklediğinizi ekleyin.

Herhangi bir büyük şirket tarafından, siparişlerini veya ihtiyaç duydukları her şeyi ele almak için dahili olarak kullanılan birçok uygulamayı göz önünde bulundurun. Web sunucuları, iş parçacığı gerektiren tek şey değil.


-2

Bazı işleme görevleri burada akla gelir. Bir görüntünün her pikseli üzerinde uzun bir ops zinciri yapıyorsanız ve bu op'lar paralelleştirilebilirse, göreceli olarak küçük bir 1024x768 görüntü bile "yüz binlerce" köşeli ayraç içindedir.


2
Birkaç yıl önce, saniyede 30 kare hızda 256x256 görüntü sıkıştırarak, gerçek zamanlı FLIR görüntü işleme yaparak birkaç yıl geçirdim. Çok sayıda DONANIM işlemci ve verilerinizi aralarında paylaşmanın sorunsuz bir yolu yoksa, yapmak istediğiniz SON iş, bağlamsal değişim, bellek çekişmesi ve gerçek hesaplama maliyetlerini düşürmek için önbellek eklemektir.
John R. Strohm 10'13

Bu yapılan işe bağlı. Yaptığınız her şey bir işi bir donanım çekirdeğine / yürütme birimine teslim ediyorsa, bunun ardından etkin bir şekilde unutabilirsiniz (ve bunun GPU'ların çalışma şeklinin, bu varsayımsal bir senaryo değil) olduğuna dikkat edin. geçerli.
Maximus Minimus
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.