Birden fazla iş parçacığı tek bir iş parçacığının yapamadığı ne yapabilir? [kapalı]


100

İş parçacığı kod yürütülmesini hızlandırabilir, ancak gerçekten gerekli mi? Her kod parçası tek bir iş parçacığı kullanılarak yapılabilir mi, yoksa yalnızca birden çok iş parçacığı kullanılarak gerçekleştirilebilecek bir şey var mı?


29
Buraya daha önce gönderilen cevapların bazılarına dayanarak, bazı açıklamaların yapıldığını düşünüyorum. Diş açmanın amacı, bilgisayarların aynı anda birden fazla şey yapmasına (görünmesine) izin vermektir. Bu işlem, tek çekirdekli bir bilgisayar kullanılarak yapılırsa, genel bir hızlanma görmezsiniz. Göreceğiniz şey engellemeyi kaldırmak; Tek iş parçacıklı bir programda, hesaplamalar yapılırken kullanıcı arabirimi engellenir. Çok iş parçacıklı bir programda, hesaplamalar arka planda gerçekleşirken kullanıcı arayüzü hala kullanılabilir.
Robert Harvey

11
Elbette, bilgisayarınızda (bugünlerde yaygın olan) birden fazla işlemci çekirdeğiniz varsa, programınız işlemlerinizi gerçekleştirmek için ek çekirdeklerden yararlanmak için iş parçacıkları kullanabilir ve hızlanacağınızı görürsünüz ; hesaplama problemin. Hiç iş parçacığı kullanmazsanız, programınız yalnızca tek bir işlemci çekirdeği kullanacaktır;
Robert Harvey, 16:

14
Tek iş parçacıklı bir program, çok iş parçacıklı bir program yapabildiği şekilde kaynakları kilitleyemez.
zzzzBov

3
Cevap: iki çekirdek üzerinde koşmak
Daniel Little

6
Cevap: kilitlenmeye neden olur.
İş

Yanıtlar:


111

Her şeyden önce, iş parçacığı kod yürütülmesini hızlandıramaz. Bilgisayarı daha hızlı çalıştırmazlar. Tek yapabilecekleri boşa harcanacak zamanı kullanarak bilgisayarın verimliliğini artırmak. Bazı işlem türlerinde bu optimizasyon verimliliği artırabilir ve çalışma süresini kısaltabilir.

Basit cevap evet. Tek bir iş parçacığında çalıştırılacak herhangi bir kod yazabilirsiniz. İspat: Tek bir işlemci sistemi talimatları yalnızca doğrusal çalıştırabilir. Birden fazla uygulama satırına sahip olmak, işletim sisteminin işlem kesintileri, mevcut iş parçacığının durumunu kaydetme ve bir başkasının başlatılması ile yapılır.

Karmaşık cevap daha karmaşık ... olduğunu! Çok iş parçacıklı programların genellikle doğrusal programlardan daha verimli olmasının nedeni, bir donanım "sorunu" nedeniyledir. CPU hesaplamaları hafızadan ve sabit depolama IO'sundan daha hızlı gerçekleştirebilir. Dolayısıyla, bir "add" komutu, örneğin, bir "getir" den çok daha hızlı bir şekilde yürütülür. Önbellek ve özel program komutunun getirilmesi (buradaki terimin tam olduğundan emin değilsiniz), bununla bir dereceye kadar savaşabilir, ancak hız sorunu devam etmektedir.

Diş açma, IO talimatları tamamlanırken CPU'ya bağlı talimatlar için CPU kullanarak bu uyumsuzlukla mücadelenin bir yoludur. Tipik bir iş parçacığı yürütme planı muhtemelen olacaktır: Veri alma, veri işleme, veri yazma. Alma ve yazma işleminin 3 döngü sürdüğünü ve işlemenin açıklama amacıyla alındığını varsayalım. Bilgisayarın okurken veya yazarken, her biri 2 döngü için hiçbir şey yapmadığını görebiliyor musunuz? Açıkçası tembel olmak ve optimizasyon kırbaçımızı kırmamız gerek!

Bu boşa harcanan zamanı kullanmak için iş parçacığı kullanarak işlemi yeniden yazabiliriz:

  1. # 1 alım
  2. işlem yok
  3. # 2 alma
  4. # 1 yapıldı, işleme koy
  5. # 1 yaz
  6. # 1 alım
  7. # 2 yapıldı, işleme koy
  8. # 2 yaz
  9. # 2 getir

Ve bunun gibi. Açıkçası bu biraz tartışmalı bir örnek, ancak bu tekniğin aksi halde IO için harcanacak zamanı nasıl kullanabileceğini görebilirsiniz.

Yukarıda gösterildiği gibi diş açmanın yalnızca yoğun GÇ bağlantılı işlemlerde verimliliği artırabileceğini unutmayın. Eğer bir program esas olarak bir şeyler hesaplıyorsa, daha fazla çalışabileceğimiz çok fazla "delik" olmayacak. Ayrıca, dişler arasında geçiş yaparken birkaç talimatın da bir üst kısmı olacak. Çok fazla iş parçacığı çalıştırırsanız, işlemci zaman değiştirmeye harcayacak ve aslında sorun üzerinde çalışmayacak. Buna devrilme denir .

Hepsi tek bir çekirdekli işlemci için iyidir ve iyidir, ancak çoğu modern işlemcinin iki veya daha fazla çekirdeği vardır. İplikler hala aynı amaca hizmet ediyor - CPU kullanımını en üst düzeye çıkarmak, ancak bu sefer aynı anda iki ayrı komut çalıştırabiliyoruz . Bu , çalışma süresini bir çok çekirdeğin etkisiyle azaltabilir, çünkü bilgisayar aslında bağlam değiştirmeyi değil, çok görevlidir.

Çoklu çekirdeklerde dişler, iki çekirdek arasında işi bölme yöntemi sağlar. Yukarıdakiler yine de her bir çekirdek için hala geçerlidir; Bir çekirdekte iki diş ile maksimum verim sağlayan bir program büyük olasılıkla iki çekirdekte yaklaşık dört diş ile zirve verimde çalışacaktır. (Burada verimlilik, minimum NOP talimatı yürütmeleri ile ölçülür.)

Çoklu çekirdeklerde (tek bir çekirdeğin aksine) akan ipliklerle ilgili problemler genellikle donanım ile halledilir. CPU, okumadan / yazmadan önce uygun bellek konumlarını kilitlediğinden emin olacaktır. (Bunun için bellekte özel bir bayrak ucu kullandığını okudum, ancak bu birkaç yolla başarılabilir.) Yüksek seviyeli dilleri olan bir programcı olarak, iki çekirdekten daha fazla bir şey için endişelenmenize gerek yok biriyle yapmak zorunda kalacaktı.

TL; DR: İşler, bilgisayarın birkaç görevi zaman uyumsuz olarak işlemesini sağlamak için işleri bölebilir. Bu, bir işlem bir kaynağı beklerken kilitlemek yerine, mevcut tüm işlem sürelerini kullanarak bilgisayarın maksimum verimlilikte çalışmasını sağlar.


17
Mükemmel cevap Sadece belirli bir noktadan sonra, daha fazla iş parçacığı eklemenin bir programı daha yavaş çalışmasını sağlayabilir , çünkü daha önce tüm "boşa harcanan" zamanın kullanıldığını ve şimdi sadece ek bağlam anahtarı ve senkronizasyon ek yükü eklediğinizi açıklamak istiyorum.
Karl Bielefeldt

8
IO engelleme işleminde iş parçacıklarının nasıl yardımcı olduğunu açıklamak için +1. İş parçacığının başka bir kullanımı, kullanıcı arayüzünün kullanıcı eylemlerini (fare hareketi, ilerleme çubukları, tuş vuruşları) işlemeye devam etmesine izin vermesidir, böylece kullanıcı algısı programın 'donmuş' olmadığı anlamına gelir.
jqa

3
Bir ek daha: kesinlikle konuşursak, konu başlıkları çoğu dile herhangi bir ifade eklemez; Kesinlikle yapmak zorundaysanız, tüm çoğullamayı kendiniz uygulayabilir ve aynı sonuçları elde edebilirsiniz. Uygulamada, bu, tüm iş parçacığı kütüphanenizi yeniden uygulamak anlamına gelir - özyineleme kesinlikle gerekli değildir, ancak kendi çağrı yığınızı yazarak taklit edilebilir.
Kilian Foth

9
@james: UI işlemeyi başka bir G / Ç biçimi olarak sınıflandırdım. Belki de en kötüsü, kullanıcılar düzensiz ve doğrusal olma eğilimindedir. :)
TMN

7
Tek bir çekirdekli veya CPU olan bilgisayarın çevresinde soru ve cevap sessiz bir varsayım var. Saatimin iki çekirdeği var, herhangi bir modern makinede geçerli olduğu varsayımından şüpheliyim.
blueberryfields

37

Birden fazla iş parçacığı tek bir iş parçacığının yapamadığı ne yapabilir?

Hiçbir şey değil.

Basit kanıtı kroki:

  • [Church-Turing Conjecture] ⇒ Hesaplanabilir olan her şey bir Universal Turing Machine ile hesaplanabilir.
  • Üniversal bir Turing Makinesi tek dişlidir.
  • Ergo, hesaplanabilecek her şey tek bir iş parçacığı ile hesaplanabilir.

Orada gizlenmiş büyük bir varsayım olduğunu, ancak, Not: Kullanılan dil yani o içindeki tek iplik Turing-tamamlandı.

Öyleyse, daha ilginç olan soru şuydu: " Turing'in tamamlanmadığı bir dile sadece çoklu iş parçacığı eklenmesi Turing'i tamamlayabilir mi?" Ve inanıyorum ki, cevap "Evet".

Toplam Fonksiyonel Dilleri alalım. [Bilinmeyenler için: Fonksiyonel Programlamanın Fonksiyonlarla Programlama Yapması gibi, Fonksiyonel Programlamanın Toplam Fonksiyonlarla Programlanması gibi.]

Toplam Fonksiyonel Diller açıkçası Turing tamamlama değildir: Bir TfpL sonsuz bir döngüye yazamaz (aslında, bu oldukça fazla olduğunu tanımı "toplam" nin), ancak yapabilirsiniz bir Turing Machine, ergo orada en az bir programı var olduğunu Bir TFPL’de yazılamaz ancak bir UTM’de yazılabilir, bu nedenle TFPL’ler UTM’lerden daha az hesaplamalı olarak güçlüdür.

Bununla birlikte, bir TFPL'ye iş parçacığı eklediğiniz anda sonsuz döngüler elde edersiniz: Yeni bir iş parçacığı içinde döngü her yinelemesini yapın. Her bir iş parçacığı her zaman bir sonuç döndürür, bu nedenle Toplam'dır, ancak her iş parçacığı bir sonraki yinelemeyi ve infinitum'u uygulayan yeni bir iş parçacığı açar.

Ben düşünüyorum bu dil Turing-tam olacağını.

En azından, orijinal soruyu yanıtlıyor:

Birden fazla iş parçacığı tek bir iş parçacığının yapamadığı ne yapabilir?

Eğer sonsuz döngüler yapamaz bir dili var, o zaman çoklu iş parçacığı sonsuz döngü yapmak için izin verir.

Elbette, bir ipliğin ortaya çıkmasının bir yan etki olduğunu ve bu nedenle genişletilmiş dilin artık sadece Toplam olmadığını, artık İşlevsel olmadığını da unutmayın.


13
Bir "kanıt" getirdiğinden beri, kendimi "iyi, aslında ..." diye düşünmekten alıkoyamam. Bence hesaplanabilirlik kavramını kötüye kullanıyorsun. Kanıt sevimli bir şey ve ben senin fikrini anlıyorum, ama gerçekten doğru soyutlama düzeyinde değil. Edememek şeyler yapmak mümkün değil aynı değildir hesaplamak Turing makinası çünkü örneğin, söylemeye belgenizi kullanamazsınız hesaplamak "Her hesaplanabilir fonksiyon" o olabilir, do 3 saniyede. Kesin konuşursak, kesintisiz tek bir dişli makine işlemcisini hesaplama yaparken meşgul ederken G / Ç'ye erişemez.
xmm0

1
Ve hiçbir gerçek bilgisayar bir Turing makinesi değildir.
Jens

1
@ColeJohnson: Bir kilitlenme bir uygulama detayıdır. Görünür çıktı "durmuyor", tek bir dişle kolayca yapılabilir.
Heinzi

1
@Heinzi: "kolayca yapılabilir" bir understatement. Yanlış hatırlamıyorsam, ben ikinci veya üçüncü bir program şimdiye yazdı tam olarak yaptım! ;-)
Joachim Sauer

1
Evren tek iplik ed ise, dize teorisi nedir? Böyle bir bilimle tartışamazsınız.
corsiKa

22

Teoride, çok iş parçacıklı bir programın yaptığı her şey tek bir iş parçacıklı programla da yapılabilir, ancak daha yavaştır.

Uygulamada, hız farkı o kadar büyük olabilir ki, görev için tek iş parçacıklı bir program kullanmanın bir yolu yoktur. Örneğin, her gece çalışan bir toplu veri işleme işiniz varsa ve tek bir iş parçacığında bitirmek 24 saatten fazla sürerse, çok iş parçacıklı hale getirmekten başka seçeneğiniz yoktur. (Uygulamada, eşik muhtemelen daha da azdır: sık sık bu güncelleme görevleri, kullanıcılar sistemi tekrar kullanmaya başlamadan önce sabahın erken saatlerinde bitmelidir. Ayrıca, diğer görevler de aynı gece boyunca bitmesi gereken bunlara bağlı olabilir. kullanılabilir çalışma zamanı birkaç saat / dakika kadar düşük olabilir.)

Bilişim işi birden çok iş parçacığı üzerinde yapmak, dağıtılmış işlem biçimidir; çalışmayı birden fazla iş parçacığı üzerine dağıtıyorsunuz. Dağıtılmış işlemlere başka bir örnek (birden fazla iş parçacığı yerine birden fazla bilgisayar kullanarak) SETI ekran koruyucusudur: tek bir işlemcide bu kadar fazla ölçüm verisinin çok uzun zaman alacağını ve araştırmacıların emeklilikten önce sonuçları görmeyi tercih ettiklerini; Uzun süredir bir süper bilgisayar kiralamak için bütçeniz yok, bu yüzden işi ucuz hale getirmek için milyonlarca ev bilgisayarına dağıtıyorlar.


SETI ekran koruyucu, bilgisayarınızda bir arka plan iş parçacığı üzerinde çalıştığı anlamında bir iş parçacığı örneğidir ; Bilgisayarınızdaki diğer şeyleri, arka planda veri sıkıştırırken hala yapabilirsiniz. İş parçacığı olmadan, SETI ekran koruyucu hesaplamaları yaparken bir duraklama olur; kendi işine devam etmeden önce bitirmesini beklemelisin.
Robert Harvey,

3
@Robert: Péter, SETI @ Home'u kullanarak, birden fazla işlemci üzerinde çalışmak için işleri bölme işini açıklamak amacıyla kullandığını düşünüyorum. Dağıtılmış hesaplama elbette çoklu kullanımdan farklıdır, ancak kavram benzerdir.
Steven

5
SETI örneğinin, mutli-thread yerine bilgisayarlara dağıtılmış olduğunu düşünüyorum. Benzer kavramlar ama aynı şey değil.

11

İplikler sıralı hesaplamadan küçük bir adım gibi görünmekle birlikte, aslında büyük bir adımı temsil eder. Sıralı hesaplamanın en temel ve çekici özelliklerini atarlar: anlaşılabilirlik, öngörülebilirlik ve determinizm. Bir hesaplama modeli olarak konu başlıkları çılgınca belirsizdir ve programcının işi bu belirtisizliğin budamasıdır.

- Konularla İlgili Sorun (www.eecs.berkeley.edu/Pubs/TechRpts/2006/EECS-2006-1.pdf).

İşleri birden fazla çekirdeğe dağıtabilmeniz için iplikler kullanarak elde edilebilecek bazı performans avantajları olsa da, genellikle büyük bir fiyata gelir.

Henüz burada bahsedilmeyen dişleri kullanmanın olumsuz yanlarından biri, tek dişli işlem alanları ile elde ettiğiniz kaynak bölümlendirme kaybıdır. Örneğin, bir segfault davasıyla karşılaştığınızı söyleyin. Bazı durumlarda, bundan dolayı suçlu çocuğun ölmesine ve yeni bir tane yeniden doğmasına izin vermeniz için çok işlemli bir uygulamada iyileşmek mümkündür. Bu, Apache'nin prefork arka ucundaki durumdur. Bir httpd örneği ortaya çıktığında, en kötü durum, söz konusu işlem için belirli HTTP isteğinin bırakılabileceği, ancak Apache'nin yeni bir çocuk ortaya çıkardığı ve genellikle yeniden gönderilip servis verildiği takdirde isteğin ortaya çıktığıdır. Sonuçta, Apache bir bütün olarak hatalı iş parçacığı ile alınmaz.

Bu senaryoda bir diğer husus, bellek sızıntısıdır. Bir iş parçacığı çökmesini dikkatlice idare edebileceğiniz bazı durumlar vardır (UNIX'de, belirli sinyallerden kurtarma - hatta segfault / fpviolation bile mümkündür), ancak bu durumda bile, bu iş parçacığı tarafından ayrılan tüm belleği sızdırmış olabilirsiniz (malloc, yeni, vb). Bu nedenle işlem devam ederken, her hata / düzelme ile zamanla daha fazla bellek sızdırıyor. Yine, Apache'nin bellek havuzlarını kullanması gibi, bunu en aza indirmenin bir dereceye kadar yolu vardır. Ancak bu hala, iş parçacığının kullanmış olabileceği üçüncü taraf liblerin tahsis ettiği hafızaya karşı korunmuyor.

Bazı insanların da belirttiği gibi, senkronizasyon ilkellerini anlamak belki de gerçekten doğru olan en zor şeydir. Kendi başına bu sorun - sadece tüm kodunuz için genel mantığı bulmak - çok büyük bir baş ağrısı olabilir. Gizemli çıkma kilitleri en tuhaf zamanlarda, bazen de programınız üretimde çalışana kadar gerçekleşmeyebilir, bu da hata ayıklamayı daha da zorlaştırır. Buna ek olarak, senkronizasyon ilkellerinin çoğu platforma (Windows ve POSIX) göre büyük ölçüde değiştiği ve hata ayıklamanın daha zor olabileceği gibi, herhangi bir zamanda yarış koşulları olasılığını (başlatma / başlatma, çalışma zamanı ve kapatma), iş parçacığı ile programlama gerçekten yeni başlayanlar için çok az merhamet vardır. Ve hatta uzmanlar için orada hala küçük bir merhamet var, çünkü diş açma bilgisi genel olarak karmaşıklığı en aza indirmiyor. Her bir iş parçacığı kodu satırı, katlanarak programın genel karmaşıklığını birleştirir ve aynı zamanda gizli bir kilitlenme ya da garip yarış koşulunun herhangi bir zamanda yüzeye çıkma olasılığını arttırır. Bunları ortadan kaldırmak için test senaryoları yazmak da çok zor olabilir.

Bu nedenle Apache ve PostgreSQL gibi bazı projeler çoğu zaman süreç tabanlı. PostgreSQL, her arka uç iş parçacığını ayrı bir işlemde çalıştırır. Elbette bu hala senkronizasyon ve yarış koşullarını hafifletmiyor, ancak oldukça fazla koruma sağlıyor ve bazı şeyleri basitleştiriyor.

Her biri tek bir yürütme iş parçacığı çalıştıran birden çok işlem, tek bir işlemde çalışan birden çok iş parçacığından çok daha iyi olabilir. AMQP (RabbitMQ, Qpid, vb.) Ve ZeroMQ gibi eşler arası yeni kodların çoğunun ortaya çıkmasıyla, farklı işlem alanlarına ve hatta makinelere ve ağlara dişleri ayırmak, işleri büyük ölçüde basitleştirerek çok daha kolaydır. Ama yine de, gümüş bir mermi değil. Başa çıkmak için hala bir karmaşıklık var. Değişkenlerinizden bazılarını işlem alanından ağa taşımanız yeterlidir.

Sonuç olarak, iplik alanına girme kararı hafif değildir. Bir kez o bölgeye ayak bastığınızda, neredeyse anında her şey daha karmaşık hale gelir ve yepyeni sorun ırkları hayatınıza girer. Eğlenceli ve havalı olabilir, ama nükleer güç gibi - işler ters gittiğinde kötü ve hızlı gidebilirler. Uzun yıllar önce kritiklik eğitimi alan bir sınıf aldığımı hatırlıyorum ve Los Alamos'ta, II. Dünya Savaşı'ndaki laboratuvarlarında plütonyum ile oynayan bazı bilim adamlarının resimlerini gösterdiklerini hatırlıyorum. Birçoğu maruz kalma olayına karşı çok az önlem aldı veya hiç bir önlem almadı ve göz açıp kapayıncaya kadar - tek bir parlak, ağrısız flaşta, hepsi onlar için bitecekti. Günler sonra öldüler. Richard Feynman daha sonra buna " ejderhanın kuyruğunu gıdıklıyor " dedi.“Bu, ipliklerle oynamanın nasıl bir şey olduğunu (en azından zaten benim için). İlk başta oldukça zararsız gözüküyor ve ısırılınca, başınızın işlerin ne kadar çabuk düştüğünü kafanızı çiziyorsunuz. Seni öldürme


TL; DR cevabım, sizin için tek bir iş parçacığının yapamayacağı bu güzel parçaya kıyasla daha güzel.
saat

1
öğleden sonra kahve molası
Mike Owens

10

Birincisi, tek bir dişli uygulama hiçbir zaman çok çekirdekli bir işlemciden veya aşırı iş parçacıklığından asla yararlanamayacaktır. Ancak, tek bir çekirdekte bile, çoklu iş parçacığı yapan tek iş parçacıklı CPU'nun avantajları vardır.

Alternatifleri ve bunun sizi mutlu edip etmediğini düşünün. Aynı anda çalışması gereken birden fazla göreviniz olduğunu varsayalım. Örneğin, iki farklı sistemle iletişiminizi sürdürmek zorundasınız. Çok iş parçacıklı olmadan bunu nasıl yapıyorsun? Muhtemelen kendi zamanlayıcınızı yaratır ve gerçekleştirilmesi gereken farklı görevleri çağırmasına izin verirsiniz. Bu, görevlerinizi parçalara ayırmanız gerektiği anlamına gelir. Muhtemelen parçalarınızın çok fazla zaman almadığından emin olmanız gereken bazı gerçek zamanlı kısıtlamaları yerine getirmeniz gerekir. Aksi halde, zamanlayıcı diğer görevlerde sona erer. Bu, görevi bölmeyi daha da zorlaştırır. Kendinizi yönetmek için ne kadar çok görev yapmanız gerekiyorsa, ne kadar bölünmüş olursanız ve zamanlamanız o kadar karmaşıklaşır ve tüm kısıtlamaları yerine getirebilir.

Birden fazla dişiniz olduğunda, hayat daha kolay olabilir. Önleyici bir zamanlayıcı, bir iş parçacığını istediği zaman durdurabilir, durumunu koruyabilir ve başka birini başlatabilir. İplik sırası geldiğinde yeniden başlatılır. Avantajları: bir zamanlayıcı yazma karmaşıklığı zaten sizin için yapıldı ve görevlerinizi bölmek zorunda değilsiniz. Ayrıca, zamanlayıcı kendinizin bile bilmediğiniz işlemleri / konuları yönetme yeteneğine sahiptir. Ayrıca, bir iş parçacığının herhangi bir şey yapması gerekmediğinde (bazı olayları bekliyor) CPU çevrimi gerektirmez. Aşağı iş parçacıklı zamanlayıcı oluştururken, bu başarmak kolay değil. (bir şeyi uykuya koymak çok zor değildir, ama nasıl uyanır?)

Çok iş parçacıklı gelişimin dezavantajı, eşzamanlılık sorunları, kilitleme stratejileri vb. Hakkında anlamanız gerektiğidir. Hatasız çoklu iş parçacıklı kod geliştirme oldukça zor olabilir. Ve hata ayıklama daha da zor olabilir.


9

sadece birden fazla iş parçacığı kullanılarak gerçekleştirilebilecek bir şey var mı?

Evet. Tek bir iş parçacığı ile birden fazla CPU'da veya CPU çekirdeğinde kod çalıştıramazsınız.

Birden fazla CPU / çekirdek olmadan, iş parçacığı hala bir sunucudaki istemci işleme gibi kavramsal olarak paralel çalışan kodu basitleştirebilir - ancak aynı şeyi iş parçacığı olmadan da yapabilirsiniz.


6

Konular sadece hız ile ilgili değil, eşzamanlılıkla da ilgilidir.

@Peter'in önerdiği bir toplu iş uygulamanız yoksa bunun yerine WPF gibi bir GUI araç takımı yoksa kullanıcılar ve iş mantığı ile tek bir iş parçacığı ile nasıl etkileşime girersiniz?

Ayrıca, bir Web Sunucusu kurduğunuzu varsayalım. Birden fazla kullanıcıya eşzamanlı olarak tek bir iş parçacığıyla nasıl hizmet edersiniz (başka işlem olmadığını varsayarak)?

Sadece basit bir iş parçacığının yeterli olmadığı birçok senaryo var. Bu yüzden 50'den fazla çekirdeğe ve yüzlerce iş parçacığına sahip Intel MIC işlemci gibi yeni gelişmeler yaşanıyor.

Evet, paralel ve eşzamanlı programlama zordur. Fakat gerekli.


3
"Sadece bir iş parçacığı" birkaç şey anlamına gelebilir - örneğin, tek bir iş parçacığı (yeşil ya da yeşil) iş parçacığında ortak çoklu görev taklitini simüle etmek için sınırlandırılmış sürekliliği kullanabilirsiniz.
Frank Shearar

Tabii, ama bahşiş için @Frank + 1 sorusuna küçük bir bağlam veriyorum.
Randolf Rincón Fadul

3
Konular daha kolay olabilir, ancak bahsettiğiniz tüm görevler iş parçacığı olmadan yapılabilir ve gerçekten eskisi gibi. Örneğin, kurallı GUI döngüsü (eski) {işlem GUI olayları; biraz hesapla}. Konu gerektirmez.
KeithB

Tek işlemli tek iş parçacıklı web sunucuları vardır. örneğin lighttpd veya thttpd veya nginx (ikincisi birden fazla işlemi çalıştırabilir, ancak varsayılanı birdir. Ayrıca her zaman tek iş parçacıklıdır). Birden fazla kullanıcıya hizmet etmekte kesinlikle problemleri yoktur.
StasM

6

Multi-Threading, GUI arayüzünün uzun işleme işlemleri sırasında hala duyarlı olmasına izin verebilir. Çok iş parçacığı olmadan, uzun bir işlem çalışırken kullanıcı kilitli bir formu izlemekte sıkışıp kalır.


Bu tamamen doğru değil. Teorik olarak, uzun operasyonlarınızı daha küçük operasyonlara bölebilir ve aralarındaki olay işlemlerini güncelleyebilirsiniz.
Sebastian Negraszus

@Ayarma N. Ama eğer uzun süreç daha küçük olanlara yeniden yansıtılamazsa? İşlemi başka bir iş parçacığında çalıştırma yeteneği GUI iş parçacığını (ana iş parçacığını) hala yanıt verebilir duruma getirebilir.
LarsTech

5

Çok iş parçacıklı kod, program mantığını kilitleyebilir ve eski iş verilerine tek iş parçacığının yapamadığı şekillerde erişebilir.

İş parçacığı, ortalama bir programcının hata ayıklaması ve bir uyarıcı programcının tam olarak bakması durumunda, aynı hatayı yakalamak için gerekli şanstan bahseden hikayelerin söylendiği bölgeye düşmesi ve tahmin edilebileceği bir bölgeden gizli bir hata alabilir. doğru an.


4

Diğer girişlere (GUI veya diğer bağlantılar) karşı da duyarlı olması gereken IO'yu engelleme ile ilgili uygulamalar tek başlarına yapılamaz

engellemeden ne kadar okunabileceğini görmek için IO kütüphanesine denetim yöntemlerinin eklenmesi buna yardımcı olabilir, ancak pek çok kütüphane bu konuda tam bir garanti vermez.


Tek dişli olabilirler (ve çoğu zaman da). Kod çekirdeğe bir miktar GÇ başlatmasını söyler ve tamamlandığında bir sinyal alır. Sinyali beklerken, diğer işlemleri yapabilir.
KeithB

@keith bu non- bloke edici IO Ben özellikle engelleme dedim
cırcır ucube

Ancak, duyarlı kalmak istiyorsanız neden G / Ç engellemeyi tercih ediyorsunuz? Genel olarak bloke edici olmayan bir alternatifi olmayan herhangi bir bloke edici IO var mı? Hiçbir şey düşünemiyorum.
KeithB

@keith java'nın RMI engelliyor ve onunla bir geri arama uygulayabilirsiniz (ama bu başka iş parçacığı oluşturur) ise ancak güvenlik duvarları tarafından bloke edilebilir
ucube mandalınızı

Tek bir dişli kodun içsel bir kısıtlaması değil, Java RMI'nin bir kısıtlaması gibi geliyor. Ayrıca, eğer RMI yapıyorsanız, sadece uzaktaki bir makinede, ayrı bir "çalıştırma" dizisine sahipsiniz.
KeithB

4

Çok iyi cevaplar var ama tam olarak söylediğimden emin değilim - Belki de bu ona bakmak için farklı bir yol sunar:

Konular sadece Nesneler veya Aktörler gibi veya döngüler için bir programlama basitleştirmesidir (Evet, if / goto ile uygulayabileceğiniz döngüler ile uyguladığınız her şey).

Konu olmadan basitçe bir durum motoru uygularsınız. Bunu birçok kez yapmak zorunda kaldım (İlk kez yaptığımda hiç duymamıştım - sadece bir "Devlet" değişkeni tarafından kontrol edilen büyük bir anahtar ifadesi yaptı). Devlet makineleri hala oldukça yaygın ancak can sıkıcı olabilir. İplerle, kazan plakasının büyük bir bölümü kaybolur.

Ayrıca, bir dilin çalışma zamanı çalışmasını çoklu CPU dostu parçalara bölmesini kolaylaştırıyorlar (Öyleyse Oyuncular, inanıyorum).

Java, işletim sisteminin HERHANGİ bir iş parçacığı desteği sağlamadığı sistemlerde "Yeşil" iş parçacıkları sağlar. Bu durumda açıkça bir programlama soyutlamasından başka bir şey olmadığını görmek daha kolaydır.


+1 - İplikler, temelde sıralı makinelerde paralellik için sadece bir soyutlama sağlar, tıpkı yüksek seviye programlama dillerinde olduğu gibi, makine kodunun bir soyutlamasını sağlar.
mouviciel

0

OS'ler, her iş parçacığının çalışma zamanının geldiği ve ardından önlendiği zaman dilimleme konseptini kullanır. Bunun gibi bir yaklaşım şu anda olduğu gibi diş açmanın yerini alabilir, ancak her uygulamada kendi zamanlayıcılarınızı yazmanız önemsizdir. Üstelik, G / Ç aygıtları ve benzerleriyle çalışmak zorundasınız. Ve donanım bölümünden biraz destek almanız gerekir, böylece zamanlayıcınızın çalışmasını sağlamak için kesintileri yapabilirsiniz. Temelde her zaman yeni bir işletim sistemi yazıyor olacaksınız.

Genel olarak diş açma, dişlilerin G / Ç için beklediği veya uyuduğu durumlarda performansı artırabilir. Ayrıca, uzun görevleri yerine getirirken, duyarlı arabirimler oluşturmanıza ve durma işlemlerine izin vermenize de olanak tanır. Ayrıca, iş parçacığı gerçek çok çekirdekli işlemcilerde işleri geliştirir.


0

İlk olarak, iş parçacığı aynı anda iki veya daha fazla şey yapabilir (birden fazla çekirdeğiniz varsa). Bunu birden fazla işlemle de yapabilirsiniz, ancak bazı görevler yalnızca birden fazla işlemin üzerine çok iyi dağılmaz.

Ayrıca, bazı görevlerde kolayca önleyemeyeceğiniz boşluklar vardır. Örneğin, diskteki bir dosyadan veri okumak ve işleminizin aynı anda başka bir şey yapmasını sağlamak zordur. Göreviniz mutlaka diskten çok fazla okuma verisi gerektiriyorsa, işleminiz ne yaparsanız yapın diski beklemek için çok zaman harcayacaktır.

İkinci olarak, iş parçacıkları, performansınız için kritik olmayan kodunuzun büyük miktarlarını optimize etmek zorunda kalmamanıza izin verebilir. Yalnızca tek bir iş parçacığınız varsa, her kod parçası performans açısından önemlidir. Engellenirse, batırılırsınız - bu işlem tarafından yapılacak hiçbir iş ilerlememizi sağlayamaz. İş parçacığı ile bir blok sadece iş parçacığı ve diğer iş parçacıklarının ortaya çıkmasını ve bu işlem tarafından yapılması gereken işleri yapmasını etkiler.

İyi bir örnek, nadiren yürütülen hata işleme kodudur. Bir görevin çok nadir görülen bir hatayla karşılaştığını ve bu hatayı gidermek için gereken kodun belleğe girmesi gerektiğini söyleyin. Disk meşgulse ve işlem yalnızca tek bir iş parçacığına sahipse, bu hatayı işlemek için kod belleğe yüklenene kadar herhangi bir ilerleme kaydedilmez. Bu, patlayıcı tepkiye neden olabilir.

Başka bir örnek ise, nadiren bir veritabanı araması yapmanız gerekebilir. Veritabanının cevap vermesini beklerseniz, kodunuz çok büyük bir gecikmeye neden olur. Ancak tüm bu kodu senkronize etme zahmetine girmek istemiyorsunuz çünkü bu aramaları yapmanız çok nadirdir. Bu işi yapmak için bir iplik ile, her iki dünyanın da en iyisini elde edersiniz. Bu işi yapmak için bir iş parçacığı olması gerektiği gibi performans kritik değildir.

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.