Neredeyse kesinlikle olma ihtimali olmayan yarış koşullarıyla ilgilenmeli miyim?


52

Ana iş parçacığının kullanıcı arabirimini neredeyse anında güncellediği ve diğer bazı iş parçacıklarının ağ üzerinden veri sorguladığı veya işi bitirmesi 5-10 saniye alacağı garanti edilen bir şey gibi bir GUI uygulaması gibi düşünelim.

Bunun için çok farklı cevaplar aldım, ancak bazı insanlar istatistiksel olarak imkansızlığın bir yarış koşulu ise, hiç endişelenme ama diğerleri % 10-53 bile olsa (“Ben çocuk sayılar üzerinde değilsin, bu duyduğum şeydi) yarış koşullarından dolayı meydana gelen bazı vudu büyülerinden, her zaman ihtiyacı olan ipliğin kilitlerini al / bırak.

Düşüncelerin nelerdir? İstatistiksel olarak imkansız durumlarda yarış koşullarını idare etmek iyi bir programlama uygulaması mıdır? veya okunabilirliği engellemek için daha fazla kod satırı eklemek tamamen gereksiz veya hatta üretken olur mu?


21
İnsanlar böyle bir şans belirttiğinde, neden kimse bu rakamı belirten kişinin eğitimi hakkında soru sormuyor? Böyle bir numarayı yedeklemeden önce istatistiklerle ilgili resmi bir eğitime ihtiyacınız vardır.
Pieter B

27
Bir fizikçi olarak, p <1E-140, p = 0 anlamına gelir. Bu evrende olmayacak. 0,00000000000000000000000000000000000000000000000000001% o çok daha büyük.
MSalters

15
Bu yarış koşulunun, isteyerek istekli bir şekilde uygulamanızı çökertmesine yol açmayacağından emin olun . Bu bir güvenlik sorununun nedeni olabilir.
toasted_flakes

27
Milyonda bir şans, on üzerinden dokuz kez meydana gelir.
Kaz Ejderha

27
"neredeyse kesinlikle oluşma şansı yok mu?" 03:00 'de üretimde olduğu ve büyük olasılıkla çok pahalı olacağı anlamına gelir.

Yanıtlar:


137

Bu gerçekten 10'da bir 10 ^ 55 olayıysa, bunun için kodlamaya gerek yoktur. Bu, işlemi saniyede 1 milyon kez yaparsanız, her 3 * 10 ^ 41 yılda bir, böcek, evrenin yaşının 10 ila 31 katı olan bir böcek alacağınız anlamına gelir. Başvurunuz, evrenin her trilyon trilyon milyar çağında yalnızca bir kez hata yaptıysa, muhtemelen yeterince güvenilirdir.

Ancak, çok ağır bir şekilde, hatanın olası bir yere yakın olmadığı konusunda bahse girerim. Hatayı anlayabiliyorsanız, en azından zaman zaman ortaya çıkacağı kesindir, bu nedenle başlangıçta doğru şekilde kodlamaya değecektir. Ayrıca, iş parçacığı başlangıçta doğru şekilde kodlarsanız, kilitleri uygun bir şekilde almaları ve serbest bırakmaları için kod gelecekte daha fazla korunur. Tüm olası yarış koşullarını yeniden analiz etmeniz, olasılıklarını tekrar hesaplamanız ve tekrarlanmayacaklarından emin olmanız gerektiğine dair bir değişiklik yaparken endişelenmenize gerek yok.


66
Yıllar önce okuduğum bir yorum hatırlattı ancak şu anda bulamıyorum "milyonda bir şans genellikle 1 Salı. +1 "bunun olası bir yere yakın olmadığını" söylediği için.
Bevan,

2
Bahis için +1. Yarış koşullarıyla baş etmenin en iyi yolu onlardan kurtulmaktır.
Blrfl

10
@Bevan "Milyon şansta A 1 genellikle gelecek Salı günü" ... bir piyango
çalmıyorsanız

22
@dasblinkenlight Ancak çoğu piyangoda kazanan birinin şansı % 100'e yaklaşıyor. Kim olduğunu tahmin etmek , şimdi sorun bu.
Bevan,

3
@Bevan: Bu soruyu okuduğumda aklımdan geçenler tam olarak neydi - referans: işte blogs.msdn.com/b/larryosterman/archive/2004/03/30/104165.aspx
Doc Brown

69

Maliyet avantajı açısından, yalnızca size yeterince fayda sağladığı zaman ek kod yazmalısınız.

Örneğin, yanlış bir iş parçacığı "yarışı kazanırsa" meydana gelebilecek en kötü şey bilginin görüntülenmeyeceği ve kullanıcının "yenile" düğmesini tıklaması gerekecekse, yarış koşullarına karşı korumayı zahmet etmeyin: Çok fazla kod yazmanın önemsiz bir şeyi düzeltmeye değmez.

Öte yandan, eğer yarış durumu bankacılık hesapları arasında yanlış para transferleri ile sonuçlanabiliyorsa, bu sorunu çözmek için ne kadar kod yazmanız gerektiğine bakılmaksızın yarış koşullarına karşı korunmanız gerekir.


20
+1: "Başarısız gibi görünen başarısızlık" ile "Başarılı gibi görünen başarısızlık" arasındaki ayrımı yapmak için. Yanlış bilgi, etki alanına bağlı olarak çok daha ciddidir.
deworde

2
+1, yarış koşullarının sonuçlarının ne olabileceği konusunda büyük bir fark yaratıyor.
Hibe

+1 Yarış koşulunun sonucu, ele alınması gerekip gerekmediğine karar vermede önemli bir faktör olmalıdır. Bir uçak kazasına neden olabilecek bir yarış durumu, kullanıcıyı bir uygulamayı yeniden açmaya zorlayabilecek bir durumdan çok farklıdır.
dürtmek

1
+1: Sonuçların muhtemelen analiz etmeniz gereken şey olduğunu ve ortaya çıkma ihtimalinin olmadığını söyleyebilirim. Eğer sonuçlar önemli değilse, çok yaygınsa, EVEN yarış koşulunu ele almanız gerekmeyebilir.
Leo,

1
Ancak bir yarış koşulunu otomatik olarak düzeltmenin daha fazla kod yazmanız gerektiği anlamına geldiğini varsaymayın. Bu, aynı zamanda, büyük miktarda bir buggy kodunu kaldırmak ve daha küçük bir kod kodu ile değiştirmek anlamına gelebilir.
JesperE

45

Bir yarış durumu bulmak zor kısımdır. Muhtemelen bu soruyu yazmak için harcayacağınız kadar zaman harcadınız. Çok daha az okunabilir hale getirdiği gibi değil. Programcılar bu gibi durumlarda senkronizasyon kodunu görmeyi bekler ve aslında neden orada olmadığını ve eklenmesi durumunda ilgisiz hatalarını gidereceğini merak ederek daha fazla zaman kaybedebilir .

Olasılıklar söz konusu olduğunda, şaşıracaksınız. Geçen yıl binlerce otomatik denemeyle yeniden üretemediğim bir yarış durumu hata raporum vardı, ancak bir müşterinin bir sistemi her zaman gördü. Bir müşterinin kurulumunda "imkansız" bir hatayı gidermek yerine, şimdi düzeltmek için 5 dakika harcamanın işletme değeri, seçim yapılmasını engeller.


1
Bu da! Diğer programcıların, kodunuzu okurken, gerekli olanı yaparak ('başarısız olması muhtemel' olsa bile) yapabilecekleri olası sorunları düşünmekten kaçının.
Casey Kuball,

Amacınız iyi alınmış (şimdi yapılan düzeltmeler daha sonra yapılanlardan daha hızlı ve daha ucuzdur) dışında hiçbir zaman sadece "şimdi düzeltmek için 5 dakika" olmayacak.
iconoclast,

2
Yarış durumu olasılığı muhtemelen de olası görünüyor bu yüzden bile, birçok faktöre bağlı olduğunu işaret için 1 sizin bir müşteri sistemde daha sık meydana gelebilir, konfigürasyon / farklı bir OS üzerinde / sonraki sürümü vb içinde
sleske

27

Kilitleri alın ve serbest bırakın. Olasılıklar değişir, algoritmalar değişir. Bu, içine girmek kötü bir alışkanlık ve bir şeyler ters gittiğinde, durmak zorunda değilsiniz ve şansınızı yanlış alıp almadığınızı merak etmek zorunda değilsiniz ...


6
Algoritmalar değişikliği için +1. Şu anda, yarış koşullarından haberdar olduğunuzda, olasılıklar düşük. Bir yıl sonra, yarış koşullarını unuttuğunuzda, bir hatanın zamanlamasını ve olasılığını önemli ölçüde değiştiren kodunuzda değişiklik yapabilirsiniz.
Phil

13

ve diğer bazı iş parçacıkları ağ üzerinden veri çağırıyor ya da işi bitirmek için 5-10 saniye alacağı garanti edilen bir şey.

Birisi performansı artırmak için bir önbellek katmanı tanıtıncaya kadar. Birdenbire, diğer sırt sırtı anında bitti ve yarış durumu, olmadığıdan daha sık ortaya çıkıyor.

Tam olarak bu birkaç hafta önce olsaydı, hatayı bulmak için yaklaşık 2 tam geliştirici gün aldı.

Bunları tanırsanız her zaman yarış koşullarını düzeltin.


8

Basit vs doğru.

Çoğu durumda, sadelik doğruluğu bozuyor. Bu bir maliyet meselesi.

Ayrıca, yarış koşulları basit istatistiklere uymama eğiliminde olan kötü şeylerdir. Her ne kadar ilgisiz gözüken bir senkronizasyon, yarış durumunuzun aniden yarım saatte olmasına neden olana kadar her şey yolunda gider. Günlükleri açmazsanız ya da kodun hatalarını giderirseniz tabii.

Bir yarış koşulunu önlemenin pragmatik bir alternatifi (zor olabilir) tespit etmek ve günlüğe kaydetmek olabilir (zor ve erken başarısızlık için bonus). Asla olmazsa, çok az şey kaybettin. Bu gerçekten gerçekleşirse, fazladan zamanını tamir etmek için sağlam bir gerekçeye sahipsin.


1
Doğrudan düzeltmek için +1 ve düpedüz düzeltmek çok karmaşıksa erken başarısız.
Martin Ba

Çoğu durumda, basitlik eksiksizliği bozar. Senkronizasyon neredeyse hiç bu durumlar arasında değildir. Neredeyse her zaman sizi (veya kodunuzu korumakla görevli zavallı adamı) ısırmaya geri dönecektir.
reirab

@reirab Ben katılmıyorum. Seyrek olayları göz önünde bulundurursanız, günlüğe kaydedilen başarısızlık düşük maliyetlidir. Örnek: Eğer kullanıcı tam bir ay geçişinde ağı değiştiriyorsa, telefon uygulamanızın 1/100 arıza oranı (çökme) varsa, siz (1/31 23:59:00 -> 2/1 00:00:00), Muhtemelen asla duymayacağım. Ancak daha sonra bir sunucudaki bağlantıda 1/10 ^ 9 çökme şansı kabul edilemez. Değişir.
ptyx

7

Yarış durumunuz güvenlikle ilgili ise, bunu önlemek için her zaman kod yazmalısınız.

Yaygın bir örnek, unix'te dosya oluşturma / açma ile ilgili yarış koşullarıdır; bazı durumlarda, yarış koşullarına sahip olan bir program, sistem arka plan programı işlemi veya Daha da kötüsü, çekirdek.

Bir yarış koşulu rastgele gerçekleşme şansına 10 ^ (- 80) sahip olsa bile , kararlı bir saldırganın bu koşulları kasten ve yapay olarak oluşturma şansı iyi olabilir.


6

Therac-25!

Therac-25 projesindeki geliştiriciler, terapötik bir XRAY makinesinde bir UI ile arayüzle ilgili bir konu arasındaki zamanlama konusunda oldukça emindiler.

Olmamalıydı.

Bu ünlü yaşam ve ölüm yazılımı felaketi hakkında daha fazla bilgi edinebilirsiniz:

http://www.youtube.com/watch?v=izGSOsAGIVQ

veya

http://en.wikipedia.org/wiki/Therac-25

Başvurunuz başarısızlığa karşı tıbbi cihazlardan daha az hassas olabilir. Yararlı bir yöntem, ortaya çıkma ihtimalinin ürünü ve üretilebilecek tüm birimler için ürünün kullanım ömrü boyunca ortaya çıkma maliyetinin ürünü olarak riske maruz kalma oranını belirlemektir.

Kodunuzu kalıcı olarak oluşturmayı seçtiyseniz (ve sizinki gibi görünüyorsa), sisteminizin içindeki veya dışındaki bilgisayarların hızı arttıkça Moore'un birkaç yılda bir kolayca sıfırlanmasını düşünmelisiniz. Binlerce kopya gönderirseniz, daha fazla sıfır alın. Kullanıcılar bu işlemi yıllarca (veya aylık) günlük yaparlarsa, birkaç tane daha alın. Google fiberin kullanıldığı yerlerde kullanılırsa, o zaman ne olacak? Kullanıcı Arabirimi çöp orta GUI işlemi toplarsa, bu yarışı etkiler mi? GUI'nizin arkasında Açık Kaynak veya Windows kütüphanesi mi kullanıyorsunuz? Buradaki güncellemeler zamanlamayı etkileyebilir mi?

Semafor, kilit, muteks, bariyer senkronizasyonu, dişler arasındaki aktiviteleri senkronize etmenin yolları arasındadır. Potansiyel olarak, bunları kullanmıyorsanız, programınızı koruyan başka bir kişi olabilir ve daha sonra, iş parçacıkları arasındaki ilişkiler hakkındaki hızlıca varsayımlar kayabilir ve yarış durumu ile ilgili hesaplama geçersiz olabilir.

Açıkça senkronize etmenizi öneriyorum, çünkü bunun bir sorun yarattığını görmeseniz bile, bir müşteri olabilir. Ayrıca, yarış koşullarınız hiçbir zaman gerçekleşmediyse bile, siz veya kuruluşunuz kodunuzu savunmak için mahkemeye çağrılırsa (Toyota birkaç yıl önce Prius'le ilgili olduğu için). Metodolojiniz ne kadar kapsamlı olursa, o kadar iyi ücret alırsınız. "Bu gibi olası bir olaya karşı böyle koruyacağız ..." demek, "kodumuzun başarısız olacağını biliyoruz, ancak bu denklemin yaşamımızda gerçekleşmeyeceğini göstermek için yazdık. "

Olasılık hesaplama başka birinden geliyor gibi geliyor. Kodunuzu biliyorlar mı ve hiçbir hata yapılmadığına güvenecek kadar onları biliyor musunuz? Bir şey için% 99.99997'lik bir güvenilirlik hesapladıysam, üniversite istatistik derslerime geri dönmeyi düşünebilir ve her zaman% 100 elde edemediğimi ve kendi kişisel güvenilirlik tahminlerimin yüzde birkaçını geri çekebileceğimi hatırlayabilirim.


1
Therac-25'ten bahsetmek için +1. Burada birçok önemli ders.
Stuart Marks

Bunun iyi bir cevap olduğunu düşünürken, hobi GUI projenizin bir yarış koşulunu ortadan kaldıramazsanız insanların ölmesine neden olmayacağını savunabilirsiniz.
marktani 11:12

Tartışacak pek bir şeyim yok, ama eğer olsaydım, kod yazdığımız zaman doğru yazmamız gerektiğini savunabilirdim. Yarış koşullarını, kodun daha basit olduğu ve belki de tek yazar olduğumuz hobi projelerimizden çıkarma alıştırması yapabilirsek, birkaç yazarın çalışmasının bir araya getirilmesi gereken iş projeleri ile uğraşırken çok daha hazır olacağız.
GeliştiriciDon

4

okunabilirliği engellemek için daha fazla kod satırı eklemek tamamen gereksiz midir, hatta verimsiz midir?

Sadelik, sadece doğru olduğu zaman da iyidir. Bu kod doğru olmadığından, gelecekteki programcılar olacak ilgili hata ararken kaçınılmaz bakmak.

Hangi yolla kullanırsanız yapın (oturum açarak, belgeleyerek veya kilitleri ekleyerek - bu maliyete bağlıdır), koda bakarken diğer programcılara zaman kazandırır.


3

Bu, içeriğe bağlı olacaktır. Onun rahat bir iPhone oyunu ise, muhtemelen değil. Muhtemelen bir sonraki insanlı uzay aracı için uçuş kontrol sistemi. Her şey, “kötü” sonucun, tespit edilen sabitleme maliyetine göre ölçülmesi durumunda ortaya çıkması durumunda sonuçların ne olduğuna bağlıdır.

Bu tür sorular için nadiren 'tek bedene uyan' bir cevap vardır, çünkü bunlar soru sorma değil , ekonomi sorularıdır.


3
"Bir sonraki insanlı uzay aracı için uçuş kontrol sistemi" KESİNLİKLE .
deworde

muhtemelen ... kesinlikle ... rokette kimin olduğuna bağlıydı :-)
GrandmasterB

3

Evet, beklenmeyenleri bekleyin. Asla olmaması gereken koşulları bulmak için saatler geçirdim (diğer halkların kodunda ^^).

Her zaman bir başkasının olması, her zaman bir temerrüde sahip olması, değişkenleri başlatması (evet, gerçekten .. bu hatalar) gibi şeyler, her yinelemede tekrar kullanılan değişkenler için döngülerinizi kontrol edin, vb.

Özellikle iş parçacığı sorunları hakkında endişe duyuyorsanız, konuyla ilgili blogları, makaleleri ve kitapları okuyun. Mevcut tema değişmez veri gibi görünüyor.


3

Sadece tamir et.

Bunu tam olarak gördüm. Bir iş parçacığı, karmaşık bir veritabanı araması yapan ve diğer iş parçacığı bir sonraki kod satırına gelmeden önce yanıtlayan bir sunucuya ağ isteği göndermeyi başarır. Olur.

Bazı müşteriler bir gün yavaş işleyen bir süre boyunca "hızlı" iş parçacığı için tüm CPU zamanlarını durduracak bir şey çalıştırmaya karar verecekler ve üzüleceksiniz :)


1

Eğer muhtemel olmayan bir yarış durumu tanıdıysanız, en azından şifreye kaydedin!

EDIT: Mümkünse düzeltebileceğimi eklemeliyim, ancak yukarıdakileri yazarken, başka hiçbir cevabın açıkça koddaki sorunu belgelemediğini söylemeliyim.


1
Evet, en azından deneyin ve algılayın ve gerçekleşirse günlüğe kaydedin. IMHO her hatayı önlememek için gayet iyi. Ama en azından birisinin bunun gerçekleştiğini ve bunun yanlış yönlendirilmeyeceğini varsaydığınızı bilmesini sağlayın.
Steve Bennett

0

Bunun nasıl ve neden olabileceğini zaten biliyorsanız, bununla da başa çıkabileceğini düşünüyorum. Tabii çok miktarda kaynak almazsa.


0

Her şey bir yarış koşulunun sonuçlarının ne olduğuna bağlı. Bence sorunuzu cevaplayan insanlar çalışma alanları için doğru. Mine, yönlendirici yapılandırma motorlarıdır. Benim için yarış koşulları ya başarılı olduğunu söylese bile sistemlerin durmasını, bozulmasını ya da yapılandırılmamasını sağlıyor. Her zaman yönlendirici başına semafor kullanırım, böylece hiçbir şeyi elle temizlemek zorunda kalmam.

Bir GUI kodumun bir kısmının hala bir yarış koşulu olduğu için bir kullanıcıya hata verilebileceği şekilde yarış koşullarına eğilimli olduğunu düşünüyorum; Böyle bir olaydan sonra uygulama.


0

Yeterince komik, son zamanlarda bu sorunla karşılaştım. Durumumda bir yarış koşulunun mümkün olduğunu bile anlamadım. Yarış durumu, yalnızca çok çekirdekli işlemciler norm haline geldiğinde kendini gösterdi.

Senaryo kabaca böyle oldu. Bir aygıt sürücüsü, yazılımın işlemesi için olayları artırdı. Cihazda zaman aşımını önlemek için kontrolün en kısa sürede cihaz sürücüsüne geri verilmesi gerekiyordu. Bunu sağlamak için, etkinlik kaydedildi ve ayrı bir dizide sıraya alındı.

Receive event from device:
{
    Record event details.
    Enqueue event in the queuing thread.
    Acknowledge the event.
}

Queueing thread receives an event:
{
    Retrieve event details.
    Process event.
    Send next command to device.
}

Bu yıllarca iyi çalıştı. Sonra aniden bazı yapılandırmalarda başarısız olur. Kuyruk iş parçacığının şimdi tek bir işlemcinin zamanını paylaşmak yerine, olay işleme iş parçacığına paralel olarak çalıştığı ortaya çıktı. Olay onaylanmadan önce bir sonraki komutu cihaza göndermeyi başararak, sıra dışı bir hataya neden oldu.

Sadece bir müşteriyi tek bir konfigürasyonda etkilediği göz önüne alındığında, utanç verici bir Thread.Sleep(1000)şekilde sorunun nerede olduğunu belirledim. O zamandan beri bir sorun olmadı.

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.