2012-02-27 15 views
8

मैं एक बहु थ्रेडेड एप्लिकेशन लिख रहा हूं और इसके लिए इकाई परीक्षण लिखने का तरीका तैयार करने की कोशिश कर रहा हूं। मुझे लगता है कि शायद यह एक और सवाल है कि यह कैसे करना है। किसी भी तरह मैं नीचे की तरह एक वर्ग अपनी सुरक्षित थ्रेड और एक इकाई परीक्षण में यह साबित करना चाहते हैं नहीं जानते हुए भी लेकिन बाहर काम नहीं कर सकता है कि यह कैसे करना है:यूनिट टेस्ट में थ्रेड सुरक्षा निर्धारित करना

public class MyClass 
{ 
    private List<string> MyList = new List<string>(); 

    public void Add(string Data) 
    { 
     MyList.Add(Data); //This is not thread safe!! 
    } 
} 
+5

एक सामान्य नियम के आप इकाई परीक्षण उपयोग नहीं कर सकते ** साबित करने के लिए के रूप में ** कि कोड है या तो धागा सुरक्षित है या नहीं थ्रेड-सुरक्षित। –

+0

@ डेविड हेफरन उम्मम्म ..... मदद! – Jon

+0

अधिकतर आपको कोड के बारे में तर्क देकर इस तरह के सत्यापन करना है।मार्क का वर्णन करने वाले प्रकार के परीक्षण बहुत उपयोगी हैं और बहुत लाभ देते हैं। लेकिन वे कुछ साबित करने से कम हो जाते हैं। –

उत्तर

11

यह साबित करना कि कुछ धागा सुरक्षित है मुश्किल है - संभवतया रोकना मुश्किल है। आप दिखा सकते हैं कि दौड़ की स्थिति का उत्पादन करना आसान है, या यह उत्पादन करना मुश्किल है। लेकिन दौड़ की स्थिति का उत्पादन नहीं करने का मतलब यह नहीं है कि यह वहां नहीं है।

लेकिन: यहां मेरा सामान्य दृष्टिकोण (यदि मेरे पास थ्रेड-सुरक्षित होना चाहिए, तो कोड का थोड़ा सा विचार करने का कारण नहीं है) एक मैनुअल रीसेट इवेंट के पीछे प्रतीक्षा करने वाले बहुत सारे धागे को स्पिन करना है। द्वार तक पहुंचने के लिए अंतिम धागा (गिनने के लिए इंटरलाक्ड का उपयोग करके) गेट खोलने के लिए ज़िम्मेदार है ताकि सभी धागे एक ही समय में सिस्टम को हिट कर सकें (और पहले से मौजूद हैं)। फिर वे काम करते हैं और सेन निकास की स्थिति की जांच करते हैं। फिर मैं इस प्रक्रिया को बड़ी संख्या में दोहराता हूं। यह आम तौर पर एक संदिग्ध थ्रेड-रेस को पुन: उत्पन्न करने के लिए पर्याप्त होता है, और यह दिखाता है कि यह "स्पष्ट रूप से टूटा हुआ" से "स्पष्ट तरीके से टूटा नहीं" (जो "टूटा नहीं" के लिए महत्वपूर्ण रूप से अलग है) से चलता है।

यह भी ध्यान दें: अधिकांश कोड को थ्रेड-सुरक्षित नहीं होना चाहिए।

+0

धन्यवाद लेकिन मैं बहुत सारे थ्रेड आधारित कोड लिखता हूं और देव टीम को अपनाने की कोशिश कर रहा हूं यूनिट-टेस्टिंग/टीडीडी ताकि हमारी सामग्री को थ्रेड सुरक्षित होना पड़े। – Jon

+0

@Mark क्या आपके पास कोई डेमो कोड उपलब्ध है? – Jon

+0

मार्क, जो आपने लिखा वह बहुत दिलचस्प लगता है, लेकिन दुर्भाग्य से यह बहुत स्पष्ट नहीं है। क्या आप अपनी प्रक्रिया को कुछ और विस्तार से वर्णित करना चाहते हैं और शायद कुछ बिंदुओं के लिए स्पष्टता जोड़ सकते हैं जैसे 'गेट तक पहुंचने के लिए अंतिम धागा (गिनने के लिए इंटरलाक्ड का उपयोग करके)' और 'गेट खोलना'? –

4

थ्रेड सुरक्षा कुछ आप मज़बूती से क्योंकि परीक्षण कर सकते हैं नहीं है अपने प्रकृति यह गैर निर्धारिती है। आप अलग-अलग धागे पर समानांतर में एक ही ऑपरेशन को कुछ सौ बार चलाने का प्रयास कर सकते हैं और देख सकते हैं कि परिणाम अंत में सुसंगत हैं या नहीं। वास्तव में बहुत अच्छा नहीं है, लेकिन मुझे लगता है कि कुछ भी बेहतर नहीं है।

+0

एमएस रिसर्च में एक बार धावक था जो सभी टकराव बिंदुओं की पहचान करेगा, जो उन्हें सी # में एक कस्टम थ्रेड शेड्यूलर का उपयोग करके एक सेब का उपयोग करेगा;) खींच लिया गया था (लंबित उत्पादीकरण, इसलिए अब एमएस पुनर्विक्रय से कोई उपलब्ध डाउनलोड नहीं है)। समस्या यह है कि आपको सभी संभावित संयोजनों को प्रमाणित करने के लिए उस प्रकार के टूल की आवश्यकता होती है, कुछ कुछ सौ रनों से उत्पादन करने के लिए बहुत कठिन हो सकते हैं क्योंकि वे केवल बहुत ही कम होते हैं। – TomTom

+0

@TomTom दिलचस्प लगता है। उत्पादन में ऐसा कुछ देखना अच्छा लगेगा। – spencercw

+0

@spencercw सहमत। मुझे लगता है कि इसके लिए एक असली ज़रूरत है! – Jon

7

मैं अक्सर यह साबित करने के लिए यूनिट परीक्षण लिखता हूं कि कोड का कुछ सेट थ्रेड सुरक्षित है। आम तौर पर, मैं उत्पादन में पाए गए बग के जवाब में इन परीक्षणों को लिखता हूं। इस मामले में, परीक्षण का उद्देश्य दर्शाता है कि बग को दोहराया जाता है (परीक्षण विफल रहता है), और नया कोड थ्रेडिंग समस्या (परीक्षण पास) को ठीक करता है, और फिर भावी रिलीज के लिए एक रिग्रेशन टेस्ट के रूप में कार्य करता है।

अधिकांश परीक्षण थ्रेड सुरक्षा परीक्षण मैंने एक धागा दौड़ की स्थिति का परीक्षण किया है, लेकिन कुछ थ्रेड डेडलॉक्स के लिए भी परीक्षण करते हैं।

सक्रिय रूप से इकाई परीक्षण कोड थ्रेड सुरक्षित थोड़ा और मुश्किल है। ऐसा नहीं है क्योंकि इकाई परीक्षण लिखना अधिक कठिन है, लेकिन क्योंकि आपको निर्धारित करने के लिए ठोस विश्लेषण करना है (अनुमान है, वास्तव में,) थ्रेड असुरक्षित हो सकता है। यदि आपका विश्लेषण सही है, तो आप एक ऐसा परीक्षण लिखने में सक्षम होना चाहिए जो तब तक विफल हो जब तक कि आप कोड थ्रेड सुरक्षित न करें।

जब एक धागा रेस स्थिति के लिए परीक्षण, मेरा परीक्षण लगभग हमेशा एक ही पैटर्न का पालन करें: (इस स्यूडोकोड है)

boolean failed = false; 
int iterations = 100; 

// threads interact with some object - either 
Thread thread1 = new Thread(new ThreadStart(delegate() { 
    for (int i=0; i<iterations; i++) { 
    doSomething(); // call unsafe code 
    // check that object is not out of synch due to other thread 
    if (bad()) { 
     failed = true; 
    } 
    } 
}); 
Thread thread2 = new Thread(new ThreadStart(delegate() { 
    for (int i=0; i<iterations; i++) { 
    doSomething(); // call unsafe code 
    // check that object is not out of synch due to other thread 
    if (bad()) { 
     failed = true; 
    } 
    } 
}); 

thread1.start(); 
thread2.start(); 
thread1.join(); 
thread2.join(); 
Assert.IsFalse(failed, "code was thread safe"); 
+0

इसे ठीक से जांचने के लिए कैसे शामिल हो रहा है क्योंकि इसमें शामिल धागे की प्रतीक्षा नहीं है एक और निष्पादन से पहले खत्म करने के लिए निष्पादित? – Jon

+2

@ जोन: एक बार "प्रारंभ()" को थ्रेड 1 और थ्रेड 2 दोनों पर बुलाया जाता है, तो वे निष्पादन शुरू करते हैं। जॉइन() केवल मुख्य थ्रेड (यूनिट टेस्ट चला रहा है) बताता है, परिणाम देखने के लिए दोनों धागे किए जाने तक प्रतीक्षा करें। थ्रेड 1 और थ्रेड 2 "रेस" में हैं, और जब वे प्रत्येक थ्रेड असुरक्षित कोड कहते हैं, तो कुछ संख्या में पुनरावृत्तियों के बाद वे विश्वसनीय कोड को खराब स्थिति में डाल देंगे। जब शामिल() निकलता है, तो मुख्य धागा यह देखने के लिए जांच सकता है कि परीक्षण सफल हुआ या विफल रहा। –

3

मैं इकाई परीक्षण की कोशिश और सूत्रण समस्याओं का पता लगाने के साथ दिया है। मैं हार्डवेयर के एक पूर्ण सेट के साथ बस एक सिस्टम लोड टेस्ट का उपयोग करता हूं, (यदि हार्डवेयर है - अक्सर मेरी नौकरियों के साथ, नेटवर्क पर यूकंट्रोलर), और एक अनजाने में बड़ी संख्या में स्वचालित क्लाइंट फ्लैट-आउट चल रहे हैं। मैं इसे एक सप्ताह तक चल रहा हूं जबकि मैं अन्य सामान करता हूं। सप्ताह के अंत में मैं भार लेता हूं और जांचता हूं कि क्या बचा है। यदि यह अभी भी काम कर रहा है, तो कोई वस्तु लीक नहीं हुई है और स्मृति में उल्लेखनीय वृद्धि नहीं हुई है, मैं इसे भेजता हूं।

के रूप में ज्यादा गुणवत्ता है कि :) के रूप में मैं बर्दाश्त कर सकते हैं

संबंधित मुद्दे