Çok iş parçacıklı yarış koşullarının test edilmesi


54

Bu cevaba yapılan yorumları okumak , özellikle:

Sadece bir test yazamadığınız için kırılmadığı anlamına gelmez. Genellikle beklendiği gibi işe yarayan tanımsız davranış (C ve C ++ bununla dolu), yarış koşulları, zayıf bir bellek modeline bağlı olarak potansiyel yeniden sıralama ... - CodesInChaos 7 saat önce

@CodesInChaos çoğaltılamazsa, o zaman 'düzeltmek' için yazılan kod da test edilemez. Ve test edilmemiş kodları canlı yayınlamak bence daha kötü bir suçtur - RhysW 5 saat önce

... test durumunda yarış koşullarının neden olduğu üretim problemlerinde çok nadir olarak meydana gelen sürekli tetiklemenin iyi bir genel yolu olup olmadığını merak ettim.


1
Her iki ucunda talimat ile (montaj) talimat adım
cırcır ucube

1
Statik analiz sıklıkla potansiyel UB'yi gösterebilir, bunun test olsa da sayılıp sayılmadığı belli değildir
jk.

Sormak için üzgünüm, fakat 'UB' ne anlama geliyor?
Doug

2
Güzel soru, bunun için olası çözümleri görmek ilginç olurdu.
RhysW

1
@ Yarış koşullarını içerebilen, ancak bunlarla sınırlı olmayan Tanımlanmamış Davranış
jk.

Yanıtlar:


85

Yaklaşık 1978'den bu yana bu çılgın iş dünyasında bulunduktan sonra, zamanının neredeyse tamamını gömülü gerçek zamanlı hesaplamada, çok görevli, çok iş parçacıklı, çok-her türlü sistemde, bazen birden fazla fiziksel işlemcide çalışarak, yarıştaki adil payımdan daha fazla kovaladım. koşullar, benim düşünceme göre sorunuzun cevabının oldukça basit olduğu yönünde.

Hayır.

Testte yarış koşullarını tetiklemenin iyi bir genel yolu yoktur.

SADECE umudunuz, onları sisteminizden tamamen tasarlamaktır.

Ne zaman ve bir başkasının doldurduğunu tespit ederseniz, bir karınca yuvasına dikkat etmeli ve sonra onu ortadan kaldırmak için yeniden tasarlamalısınız. Onun sahte pasini sisteminizden çıkardıktan sonra ortaya çıkardıktan sonra, onu karıncalardan serbest bırakabilirsiniz. (Eğer karıncalar onu zaten tüketmişlerse, sadece kemik bırakarak, "Bu, yarış koşullarını XYZ projesine koyan insanlara olur!" Ve LEAVE HIM VAR.


22
Tamamen katılıyorum. Başka bir deyişle, şakaya çok benziyor - Hasta: "Doktor, bunu yaptığımda canım yanıyor ..." Doktor: "O zaman yapmayı bırak!"
Mark Rushakoff

Güzel cevap Bir şey test edilemeyen bir soruna neden olursa, başlamak için onunla birlikte çalışmayı deneyin, sorunu tamamen önleyin!
RhysW

Tek sorum şu: Ne kadar büyük bir karınca yuvası kullanmalıyım? (+1 BTW).
Peter K.

15
Doğru telaffuz +1 gaf . (Ve cevabın geri kalanı.)
Blrfl

1
@PeterK. Bu büyük monitörler, RAM ve disk sürücüleri ile birlikte, yazılım geliştirme o birkaç olgudan biridir IS iyi.
John R. Strohm

16

Ms takım zincirindeyseniz. Ms araştırma her çalışma için yeni interlevings zorlar ve bunun denilen çalışır başarısız yeniden bir araç yarattı satranç .

İşte kullanımda gösteren bir video .


5
Bu etkileyici görünüyor; Bir noktada denemek için zaman bulmam gerekecek.
Dan Neely,

16

Bu tür problemler için bildiğim en iyi araç Valgrind'in Helgrind adlı bir uzantısı .

Temelde Valgrind sanal bir işlemciyi simüle eder ve ikilinizi (değiştirilmemiş) üzerinde çalıştırır, böylece belleğe her erişimi kontrol edebilir. Bu çerçeveyi kullanarak, Helgrind saat sistemi, paylaşılan bir değişkene erişimin karşılıklı dışlama mekanizması tarafından gerektiği gibi korunmadığı sonucuna varır. Bu şekilde, gerçekleşmemiş olsa bile teorik bir yarış durumunu tespit edebilir.

Intel, Intel Inspector adlı benzer bir araç satıyor .

Bu araçlar harika sonuçlar verir, ancak analiziniz sırasında programınız oldukça yavaşlar.


1
hala bir * nix aracı mı?
Dan Neely

1
Evet, Linux, MacOSX, android ve bazı BSD: valgrind.org/info/platforms.html
Julien

1
ThreadSanitizer benzer bir araçtır. Helgrind'den farklı olarak çalışır, bu daha hızlı olma avantajını sağlar, ancak takım zincirine entegrasyon gerektirir.
Sebastian Redl,

7

Çok iş parçacıklı bir hatanın ortaya çıkması, farklı yürütme iş parçacıklarının adımlarını belirli bir ara sırayla gerçekleştirmeleri için zorlamayı gerektirir. Genelde bu manuel olarak hata ayıklama yapmadan veya bu harmanlamayı kontrol etmek için bir tür "tanıtıcı" elde etmek için kodu değiştirmeden yapmak zordur. Ancak tahmin edilemeyecek şekilde davranan kodun değiştirilmesi, genellikle bu öngörülemezliği etkileyecektir, bu nedenle otomatikleştirmek zordur.

Pratik API Tasarımında Jaroslav Tulach tarafından güzel bir numara tarif edilmiştir : eğer söz konusu kodda log ifadeleri varsa , bu log ifadelerinin tüketicisini (örneğin enjekte edilmiş sahte terminal) belirli bir bireysel bireysel mesaj mesajlarını kabul edecek şekilde değiştirin. içeriğine göre sipariş. Bu, zaten bulunmayan üretim koduna bir şey eklemek zorunda kalmadan, farklı dişlerdeki adımların birleştirilmesini kontrol etmenizi sağlar.


2
Enjekte edilen depoları kullanmadan önce, benzer araya sokmak istediğim dizgiyi zorlamak üzere işleyen iplikleri uyumaya benzer. Bunu yapan bir kod yazdıktan sonra yukarıdaki +1 @ John'un cevabına meyilliyim. Cidden, bu şeyler doğru şekilde kullanmak için çok acı vericidir ve yine de sadece en iyi tahmin garantilerini verir çünkü farklı sonuçlarla biraz farklı araya girmeler olabilir; daha iyi bir yaklaşım, tüm olası yarış koşullarını statik analizler veya ortak paylaşılan tüm durumlar için kodun dikkatlice birleştirilmesiyle ortadan kaldırmaktır
Jimmy Hoffa

6

Çeşitli tanımsız davranış türlerinin (özellikle yarış koşullarında) mevcut olmadığından kesinlikle emin olmanın bir yolu yoktur.

Bununla birlikte, bu tür durumları iyi gösteren birçok araç vardır. Düzeltmenizin geçerli olduğunu kanıtlayamasanız bile, şu anda bu tür araçlarla ilgili bir sorun olduğunu kanıtlayabilirsiniz.

Bu amaç için bazı ilginç araçlar:

Valgrind bir hafıza denetleyicisidir. Bellek sızıntılarını bulur, başlatılmamış belleği okur, sivri uçlu işaretçi kullanımı ve sınır dışı erişim.

Helgrind iş parçacığı güvenlik denetleyicisidir. Yarış koşullarını bulur.

Her ikisi de dinamik enstrümantasyonla çalışır, yani programınızı olduğu gibi alır ve sanallaştırılmış bir ortamda çalıştırır. Bu onları müdahalesiz ama yavaş yapar.

UBSan tanımsız bir davranış denetleyicisidir. Tamsayı taşmaları, aralık dışı değişimler ve benzeri şeyler gibi çeşitli C ve C ++ tanımsız davranış durumlarını bulur.

MSan bir hafıza denetleyicisidir. Valgrind ile benzer hedefleri var.

TSan iş parçacığı güvenlik denetleyicisidir. Helgrind ile benzer hedefleri var.

Bu üç Clang derleyicisine yerleştirilmiştir ve derleme zamanında kod üretir. Bu, onları başlangıç ​​sürecinize (özellikle Clang'la derlemeniz gerekir) inşa etme sürecinize entegre etmeniz gerektiği anlamına gelir; bu, başlangıçta * eziyete göre ayarlamalarını çok daha zorlaştırır, ancak diğer yandan, çalışma süreleri çok daha düşüktür.

Listelediğim tüm araçlar Linux üzerinde, bazıları MacOS'ta çalışıyor. Henüz Windows'ta hiçbir çalışmanın güvenilir olmadığını düşünüyorum.


1

Buradaki cevapların çoğu, bu soruyu "yarış koşullarını otomatik olarak nasıl saptayabilirim?" Olarak gösteriyor. soru gerçekten ne zaman "onları bulduğumda sınamadaki yarış koşullarını nasıl yeniden üretebilirim?"

Bunu yapmanın yolu, kodunuzda yalnızca test amacıyla kullanılan senkronizasyonu tanıtmaktır. Örneğin, Etkinlik X, Etkinlik A ile Etkinlik B arasında olduğunda bir yarış durumu meydana gelirse, uygulamanızı test etmek için Etkinlik X'in Etkinlik A'dan sonra gerçekleşmesini bekleyen bir kod yazın. Büyük olasılıkla, testlerinizin uygulamanızla konuşması için bir yol göstermeniz gerekecek ("hey, bu şeyi test ediyorum, bu yüzden bu konumda bu olayı bekleyin").

Node.js ve mongo kullanıyorum, burada bazı eylemler birden fazla koleksiyonda tutarlı veri oluşturmayı içerir. Bu gibi durumlarda, birim testlerim, "Olay X için bir bekleme ayarladı" diyerek başvuruyu arayacak ve başvuru bir kez kurulduktan sonra, olay X için yapılan test çalışacak ve testler daha sonra söyleyecektir. uygulama ("Olay X için beklemede bulundum") böylece testlerin geri kalanı normal şekilde çalışacaktır.

Buradaki cevap, bu tip bir şeyi python bağlamında detaylı olarak açıklar: https://stackoverflow.com/questions/19602535/how-can-i-reproduce-the-race-conditions-in-this-python-code- güvenilir

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.