Çoklu iş parçacılığının neden zor olduğunu nasıl açıklayabilirim?


84

Ben oldukça iyi bir programcıyım, patronum da oldukça iyi bir programcı. Çoklu iş parçacığı ve bunun ne kadar zor olabileceği gibi bazı görevleri hafife almış gibi görünse de (birkaç iş parçacığı çalıştırmaktan, her şeyin bitmesini bekledikten sonra sonuçları döndürmekten başka bir şey için çok zor buluyorum).

Kilitlenmeler ve yarış koşulları hakkında endişelenmeye başladığınız an, bunu çok zor buluyorum, ancak patron bunu takdir etmiyor gibi görünüyor - buna hiç rastlamadığını sanmıyorum. Sadece bir tokat tokatlamak hemen hemen tutumdur.

Öyleyse onu nasıl tanıtabilir veya neden eşzamanlılık, paralellik ve çoklu iş parçacılığının karmaşıklığını hafife aldığını açıklayabilirim? Ya da belki yanılıyorum?

Düzenleme: Yaptığı şey hakkında biraz - bir liste boyunca döngü yapın, o listedeki her öğe için o öğedeki bilgilere dayanarak bir veritabanı güncelleme komutu yürüten bir iş parçacığı oluşturun. Aynı anda kaç tane iplik çalıştırıldığını nasıl kontrol ettiğinden emin değilim, sanırım çok fazla koşma olsaydı onları bir kuyruğa eklemiş olmalıydı (semafor kullanmazdı).


17
Çoklu iş parçacığı kolaydır. Doğru senkronizasyon zordur.
Vineet Reynolds

33
Üç kişiyi odaya, tercihen farklı vurgular ile getirin ve aynı anda eşzamanlılık probleminin farklı, örtüşen kısımlarını açıklamalarını isteyin.
greyfade

Çoklu kullanım, eldeki soruna ve dil desteğine bağlı olarak çok zor veya çok kolay olabilir. Clojure kolaylaştırır clojure.org/concurrent_programming
Job

4
@Job Eşzamanlı programlama, hangi dili kullanıyor olursanız olun (gerçek dünya projelerinde) her zaman zordur. Scala, Clojure veya Erlang, değişken durumları kullanan ve teşvik eden dillerle karşılaştırmak istediğinizde biraz daha mantıklı olur.
Chiron

4
Bunun için en sevdiğim metafor: "Aynı anda uyku ilacı ve müshil alabilir misiniz?" Hatta karmaşık mesaj sıralarını kullanarak, sipariş eşzamanlılık meyvesidir doğru yapılması . Bununla, çok fazla deneyiminiz olmadığı sürece, birçok insan için zordur .
Tim Post

Yanıtlar:


29
  1. Herhangi bir matematiksel deneyime güvenebiliyorsanız, esasen deterministik olan normal bir yürütme akışının birkaç iplikle nasıl belirlenemeyen hale gelmediğini, üstel olarak karmaşık hale geldiğini gösterin , çünkü makine talimatlarının her bir araya getirilmesinin hala doğru olanı yapmasını sağlamak zorundasınız. Kayıp bir güncelleme veya kirli okuma durumuna basit bir örnek genellikle bir göz açıcıdır.

  2. "Bu bir kilit tokat" olduğunu önemsiz çözüm tüm sorunlarını çözer ... eğer sen performansı hakkında endişe değiliz. Örneğin Atlanta'da bir kişi bir kitap sipariş ettiğinde Amazon tüm doğu kıyılarını kilitlemek zorunda kalırsa, performansın ne kadar olacağını ispatlamaya çalışın!


1
Matematiksel karmaşıklığın tartışılması için +1 - işte ortak-devlet eşzamanlılığındaki zorluğu anlamaya başladım ve genel olarak mesaj ileten mimarileri savunurken yaptığım argüman bu. "Kilitlemek için -1" ... İfadesi kilitlerin kullanımına büyük olasılıkla kilitlenmeye yol açacak veya tutarsız davranışa yol açacak, düşünülmeyen bir yaklaşımı ifade eder (kodunuzun farklı iş parçacıklarında yaşayan müşterileri birbiriyle çelişirse) istekler, ancak kendi aralarında senkronize etmeyin, istemciler, kütüphanenizin durumuyla uyumlu olmayan modellere sahip olur).
Aidan Cully

2
Amazon , bir siparişi işlerken bir malın envanterini bir depoda kısaca kilitlemek zorundadır. Belirli bir maddede ani ve büyük bir hareket varsa, o ürün için sipariş performansı, tedarik tükenene ve envantere erişim salt okunur hale gelinceye kadar (ve bu nedenle% 100 paylaşılabilir hale gelene kadar) zarar görecektir. Amazon'un diğer programların yapmadığı bir şey var, bir yeniden stoklama gerçekleşene kadar siparişleri sıraya sokma yeteneği ve yeni bir sipariş için yeniden stoklama yapılmadan önce sıraya alınmış siparişleri sunma seçeneği.
Blrfl

@Blrfl: Programlar , kuyruklardan geçen bir mesajı kullanmak için yazılmışlarsa bunu yapabilir . Tüm mesajların belirli bir diziye tek bir
sıradan

4
@Donal Fellows: Bir depoda stokta 1M widget varsa ve 1M siparişleri aynı anda gelirse, bu taleplerin tümü nasıl işlenirse yapılsın siparişlerle eşleşirken bazı seviyelerde serileştirilir. Pratik gerçek şu ki, Amazon envanterinde hiçbir zaman o kadar fazla widget bulunmuyor ki, envanter tükenmeden ve sıradaki herkese (paralel olarak) söylenmeden önce, siparişlerin işlenmesindeki gecikme kabul edilemez derecede artar. " İleti sıraları kilitlenmeleri önlemenin harika bir yoludur, ancak sınırlı bir kaynak için yüksek çekişme sorununu çözmezler.
Blrfl

79

Multi-Threading olan basit. Çoklu iş parçacığı için bir uygulamayı kodlamak çok, çok kolaydır.

Basit bir hile var ve bu, dişler arasında veri iletmek için iyi tasarlanmış bir mesaj kuyruğu kullanmak ( kendi yolunuzu değil ) kullanmaktır.

Zor kısım, birden fazla iş parçacığının paylaşılan bir nesneyi bir şekilde sihirli bir şekilde güncellemesine çalışıyor. İşte o zaman hataya açık hale geliyor, çünkü millet mevcut olan yarış koşullarına dikkat etmiyor.

Çoğu kişi ileti kuyruğu kullanmaz ve paylaşılan nesneleri güncellemeye çalışır ve kendileri için sorun yaratır.

Zor olan, birkaç sıra arasında veri aktarırken iyi çalışan bir algoritma tasarlamaktır. Bu zor. Ancak birlikte varolan dişlerin mekaniği (paylaşılan kuyruklar yoluyla) kolaydır.

Ayrıca, iş parçacıklarının G / Ç kaynaklarını paylaştığını unutmayın . Bir G / Ç'ye bağlı programın (yani ağ bağlantıları, dosya işlemleri veya veritabanı işlemleri) pek çok iş parçacığıyla daha hızlı ilerlemesi pek mümkün değildir.

Paylaşılan nesne güncelleme problemini göstermek istiyorsanız, bu basit. Masanın karşısında bir sürü kağıt kartla oturun. Sayfada çok fazla alan olan 4 veya 6 basit formül - basit bir hesaplama kümesi yazın.

İşte oyun. Her biriniz bir formül okudunuz, bir cevap yazdınız ve cevabı veren bir kart yerleştirin.

Her biriniz işin yarısını yapacaksınız, değil mi? Zamanın yarısında işin bitti değil mi?

Patronunuz çok fazla düşünmezse ve sadece başlarsa, bir şekilde çelişkiyi ortadan kaldıracaksınız ve her ikisi de aynı formüle cevap yazacaksınız. Bu işe yaramadı çünkü yazmadan önce okuduğunuz ikinizin de içsel bir koşul var. Hiçbir şey sizi aynı formülü okumanızı ve birbirinizin cevaplarının üzerine yazmanızı engelleyemez.

Kötü ya da kilitlenmemiş kaynaklarla yarış koşulları yaratmanın birçok, çok yolu vardır.

Tüm çatışmalardan kaçınmak istiyorsanız, kağıdı bir formül yığınına kesti. Kuyruktan bir tane çıkar, yanıtı bir yere yaz ve cevapları gönder. Çatışma yok çünkü ikiniz de yalnızca bir okuyucudan oluşan bir mesaj kuyruğundan okudunuz.


Kağıdı bir yığına doldurmak bile işleri tamamen düzeltir - aynı şekilde patronunuzla aynı formda yeni bir formüle erişme durumunuz vardır ve parmak ekleminizi onun içine sokarsınız. Aslında bunun en yaygın diş çekme probleminin temsilcisi olduğunu söyleyebilirim. Gerçekten brüt hatalar erken bulunur. Gerçekten alışılmadık hatalar sonsuza dek sürüyor çünkü kimse onları üretemiyor, Uygun yarış koşulları - bunun gibi - sınamaya devam ediyor ve sonunda hepsi (veya daha büyük olasılıkla) ütüler.
Airsource Ltd,

@AirsourceLtd "Knuckle'larını onunla boğarak" ile tam olarak ne diyorsunuz? İki farklı parçanın aynı mesajı almasını önleyen bir mesaj sıranız olduğu sürece, sorun olmaz. Ne demek istediğini yanlış anlamadığım sürece.
Zack,

25

Çok iş parçacıklı programlama muhtemelen eşzamanlılık için en zor çözümdür. Temel olarak, makinenin gerçekte yaptıklarından çok düşük düzeyde bir soyutlamadır.

Gibi yaklaşımlar, bir dizi var aktör modeli veya (yazılım) işlem bellekte çok daha kolay. Veya değişmez veri yapılarıyla (listeler ve ağaçlar gibi) çalışmak.

Genel olarak, endişelerin uygun bir şekilde ayrılması çoklu iş parçacılığını kolaylaştırır. Bir şey, hepsi sık sık unutulan, insanlar 20 iş parçacığı doğduğunda, hepsi aynı tamponu işlemeye çalışıyor. Senkronizasyona ihtiyaç duyduğunuz reaktörleri kullanın ve genellikle mesaj kuyrukları olan farklı çalışanlar arasında veri iletir.
Uygulama mantığınızda bir kilit varsa, yanlış bir şey yaptınız.

Bu yüzden, evet, teknik olarak, çok iş parçacıklı zor.
"Kilitlemek için bir tokat" hemen hemen eşzamanlılık sorunları için en az ölçeklenebilir bir çözümdür ve aslında çoklu iş parçacığı tüm amaçlarını yener. Bu, bir sorunu eşzamanlı olmayan bir yürütme modeline geri döndürmektir. Ne kadar çok yaparsanız, o kadar çok olasıdır, o sırada yalnızca bir iş parçacığı (veya bir kilitlenme 0'da) çalışıyor olabilir. Tüm amacı yendi.
Bu, "3. dünyanın sorunlarını çözmek kolaydır. Sadece bir bomba atmak" gibi bir şey. Sırf önemsiz bir çözüm olduğu için, sorunun kalitesini önemsiz gösterdiğinizden bu problemi önemsiz hale getirmez.

Ancak pratikte bu problemleri çözmek diğer programlama problemleri kadar zordur ve en uygun soyutlamalarla yapılır. Bu aslında onu oldukça kolaylaştırır.


14

Bence bu sorunun teknik olmayan bir yönü var - IMO bu bir güven meselesi. Örneğin, - bilmiyorum - Facebook gibi karmaşık uygulamaları yeniden üretmemiz isteniyor. Bir görevin karmaşıklığını açıklanmamış / yönetime açıklamak zorunda kalırsanız - o zaman Danimarka'da bir şeylerin çürümüş olduğu sonucuna vardım.

Diğer ninja programcıları görevi 5 dakika içinde yapabilse de, tahminlerin kişisel yeteneğine dayanıyor. Konuşmacınız ya konuyla ilgili fikrinize güvenmeyi öğrenmeli ya da sözlerini kabul etmeye istekli birini işe almalı.

Buradaki zorluk, insanların ya görmezden gelme eğiliminde oldukları ya da konuşma yoluyla kavrayamadıkları teknik sonuçları aktarmakta değil, karşılıklı saygı ilişkisi kurmakta.


1
İlginç bir cevap, teknik bir soru olsa da. Bununla birlikte, söylediklerinize katılıyorum ... bu durumda, menajerim oldukça iyi bir programcı, ancak sanırım sadece çok iş parçacıklı uygulamaların karmaşıklığına rastlamadığı için onları hafife alıyor.
Bay Shoubs

6

Kilitlenmeleri anlamak için basit bir düşünce deneyi " yemek felsefecisi " problemidir. Yarış koşullarının ne kadar kötü olabileceğini tanımlamak için kullanma eğilimimdeki örneklerden biri Therac 25 durumudur.

"Sadece bir tokat kilitlemek", çoklu iş parçacığı ile zor hatalarla karşılaşmamış birinin zihniyetidir. Ve mümkündür o durumun ciddiyetini overstating düşünüyor (I do not - özellikle arabalarda biter gömülü yazılım ile, malzeme patlatmak veya yarış durumu böcek insanları öldürmek için mümkündür).


1
yani sandviç problemi: bir yığın sandviç yapıyorsunuz, fakat sadece 1 tereyağı tabağı ve 1 bıçağı var. Genel olarak herkes iyidir ama sonunda birisi bıçağı tutarken biri tereyağını kapar .. ve sonra ikisi de orada durur, diğeri kaynağını bırakmasını bekler.
gbjbaanb

Bu gibi kilitlenme sorunları, kaynakları her zaman belirli bir düzende edinerek çözülebilir mi?
compman

@compman, hayır. Çünkü, iki iş parçacığının aynı anda aynı kaynak için yakalamayı denemesi mümkündür ve bu iş parçacığının aynı kaynak kümesine gereksinim duyması gerekmez - yalnızca sorunlara neden olacak kadar bir örtüşme. Bir şema kaynağı "geri" koymak ve ardından tekrar kapmak için rastgele bir süre beklemektir. Bu geri çekilme süresi, en erken Aloha olan birkaç protokolde gerçekleşir. en.wikipedia.org/wiki/ALOHAnet
Tangurena

1
Programdaki her kaynağın bir numarası varsa ve bir iş parçacığı / işlemi bir dizi kaynağa ihtiyaç duyduğunda, kaynakları her zaman artan sayıdaki sırayla kilitlerse ne olur? O çıkmazın olabileceğini sanmıyorum.
compman

1
@compman: Bu gerçekten kilitlenmeyi önlemenin bir yoludur. Bunu otomatik olarak kontrol etmenizi sağlayan araçlar tasarlamak mümkündür; Bu nedenle, uygulamanızın artan sayısal sıralamanın dışındaki kaynakları hiçbir zaman kilitlemediği tespit edilirse, potansiyel bir kilitlenmeniz olmadı . (Potansiyel kilitlenmelerin, kodunuz bir müşterinin bilgisayarında çalışırken yalnızca gerçek kilitlenmelere dönüşeceğini unutmayın).
gnasher729

3

Eşzamanlı uygulamalar deterministik değildir. Son derece az miktarda genel kod söz konusu olduğunda, programcı savunmasız olarak tanınır, bir iş parçacığının / işleminin bir parçasının başka bir iş parçacığının herhangi bir parçasına göre ne zaman uygulanacağını kontrol edemezsiniz. Test etmek daha zor, daha uzun sürüyor ve eşzamanlılıkla ilgili tüm kusurları bulmak pek mümkün değil. Kusurlar, eğer bulunursa, süptil olup, sürekli olarak çoğaltılamaz, bu nedenle sabitleme zordur.

Bu nedenle, tek doğru eşzamanlı uygulama, yazılım geliştirmede sık sık uygulanmayan, kesin olarak doğru olan bir uygulamadır. Sonuç olarak, S.Lot tarafından verilen cevap en iyi genel tavsiyedir, çünkü mesaj iletmenin doğru olduğunu kanıtlamak nispeten kolaydır.


3

İki kelimeyle kısa cevap: GÖZLENEBİLİR NONDETERMİNİZM

Uzun cevap: Sorunu verdiğiniz eşzamanlı programlamaya hangi yaklaşımı kullandığınıza bağlıdır. Yazarlar Kavramları, Teknikleri ve Bilgisayar Programlama Modelleri kitabında , yazarlar eşzamanlı programlar yazmak için dört ana pratik yaklaşımı açıkça açıklar:

  • Sıralı programlama : eşzamanlılığı olmayan bir temel yaklaşım;
  • Beyannameli eşzamanlılık : gözlemlenebilir bir tanımlanamazlık olmadığında kullanılabilir;
  • İleti ileten eşzamanlılık : her bir varlığın iletiyi sıralı olarak işlediği, çok sayıda varlık arasında geçen eşzamanlı ileti;
  • Paylaşılan durum eşzamanlılığı : iri taneli pasif nesneleri kaba taneli atomik işlemlerle, örneğin kilitler, monitörler ve işlemler;

Şimdi, bu dört yaklaşımın en açık olanı, sıralı programlamadan ayrı olarak bildirici eşzamanlılıktır , çünkü bu yaklaşımı kullanarak yazılan programların gözlemlenebilecek hiçbir tespit edilemezliği vardır . Başka bir deyişle, herhangi bir yarış koşulu yoktur , çünkü yarış koşulu sadece gözlemlenebilir bir klasik olmayan davranıştır.

Ancak, gözlemlenemeyen sıradancılık eksikliği, bildirimsel eşzamanlılık kullanarak ele alamayacağımız bazı sorunlar olduğu anlamına gelir . İşte son iki kolay olmayan yaklaşımın devreye girdiği yer burasıdır. Çok kolay olmayan kısım, gözlemlenebilir dinametizmizmin bir sonucudur. Şimdi ikisi de durum eşzamanlı eşzamanlı modelin altına giriyor ve aynı zamanda ifadeyle eşdeğerdir. Fakat CPU başına gittikçe artan sayıda çekirdek sayısı nedeniyle, endüstrinin mesaj geçişi eşzamanlılığına, mesaj gönderme kitaplıklarının (örn . JVM için Akka ) veya programlama dillerinin (örn. Erlang ) yükselişinde görüldüğü gibi daha fazla ilgi gösterdiği görülmektedir. .

Teorik bir Aktör modeliyle desteklenen daha önce bahsedilen Akka kütüphanesi, daha fazla kilit, monitör veya işlemle uğraşmanız gerekmediğinden eşzamanlı uygulamaları oluşturmayı basitleştirir. Öte yandan, çözüm tasarlamaya farklı bir yaklaşım gerektirir, yani oyuncuları hiyerarşik olarak nasıl birleştireceklerini düşünme. Biri, tamamen farklı bir zihniyet gerektirdiğini söyleyebilirdi; bu, sonunda düz devlet ortak eşzamanlılığını kullanmaktan daha zor olabilir.

Eşzamanlı programlama gözlemlenemeyen sıradancılık nedeniyle zordur , ancak verilen problem için doğru yaklaşımı ve bu yaklaşımı destekleyen doğru kütüphaneyi kullanırken, pek çok sorundan kaçınılabilir.


0

İlk önce, 2 iş parçacığını başlatan ve aynı zamanda 1-100 arasında aynı anda konsola yazdırmasını sağlayan basit bir program görerek sorunları ortaya çıkardığı öğretildi. Onun yerine:

1
1
2
2
3
3
...

Bunun gibi bir şey daha olsun:

1
2
1
3
2
3
...

Tekrar çalıştırın ve tamamen farklı sonuçlar elde edebilirsiniz.

Çoğumuz, kodumuzun sırayla uygulanacağını varsaymak için eğitildi. Çok parçacıklı işlerde bunu "kutudan çıkar" için kabul edemeyiz.


-3

Çekiçleri tutanlar arasında iletişim olmadan bir kerede çok sayıda aralıklı çiviyi ezmek için birkaç çekiç kullanmayı deneyin (gözlerinin bağlı olduğunu farz edin).

Bunu bir ev inşa etmeye teşvik edin.

Artık geceleri uyumak için mimar olduğunuzu hayal edin. :)


-3

Kolay kısım: semaforlar, sıralar, kilitli sayaçlar, atomik kutulu tipler vb. Gibi çerçevelerin, işletim sistemlerinin ve donanımın çağdaş özellikleriyle çoklu kullanım kullanın

Zor kısım: özellikleri ilk etapta hiçbir özellik kullanmadan uygulayın, sadece çok sayıda çekirdek üzerinde saat tutarlılığı garantilerine dayanarak, çok az sınırlı donanım kabiliyeti dışında olabilir.


3
Zor kısım gerçekten daha zor, ama bu kolay kısım bile o kadar kolay değil.
PeterAllenWebb
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.