2011-01-06 15 views
8

में एक ही नंबर देता है मैं निम्नलिखित वर्गRandom.Next() कभी कभी अलग धागे

class Program 
{ 
    static Random _Random = new Random(); 

    static void Main(string[] args) 
    { 
     ... 
     for (int i = 0; i < no_threads; ++i) 
     { 
     var thread = new Thread(new ThreadStart(Send)); 
     thread.Start(); 
     } 
     ... 
    } 

    static void Send() 
    { 
     ... 
     int device_id = _Random.Next(999999); 
     ... 
    } 
} 

कोड धागे की निर्धारित संख्या, हर एक शुरू होता है बनाता है, और प्रत्येक थ्रेड एक यादृच्छिक device_id प्रदान करती है। किसी कारण से, बनाए गए पहले दो धागे अक्सर device_id होते हैं। मैं यह नहीं समझ सकता कि ऐसा क्यों होता है।

+0

यह सांख्यिकीय रूप से सही है, के रूप में यदि आप 2 पासा फेंक वे कुछ समय आप एक ही नंबर दे, प्लस रैंडम सुरक्षित थ्रेड नहीं है - > http://blogs.msdn.com/b/pfxteam/archive/2009/02/19/9434171.aspx – dvhh

+3

@ मिच: किसी भी लिंक किए गए प्रश्न एक ही स्थिति से निपट रहे हैं। यह केवल थ्रेड सुरक्षा है जो यहां प्रासंगिक है, क्योंकि रैंडम का केवल एक उदाहरण है। –

+0

@ जोन: हाँ, यह सच है। –

उत्तर

23

यादृच्छिक थ्रेड-सुरक्षित नहीं है - आपको एकाधिक थ्रेड से एक ही उदाहरण का उपयोग नहीं करना चाहिए। यह एक ही डेटा को वापस करने से बहुत खराब हो सकता है - इसे कई धागे से उपयोग करके, आप इसे एक राज्य में "अटक" कर सकते हैं जहां यह हमेशा वापसी 0, आईआईआरसी होगा।

जाहिर है आप नहीं है बस में लगभग एक ही समय प्रत्येक थ्रेड के लिए एक नया उदाहरण बनाने के लिए, के रूप में वे एक ही बीज के साथ खत्म हो जाएगा चाहते हैं ...

मैं एक article जो में चला जाता है इसका विवरण और एक कार्यान्वयन प्रदान करता है जो वृद्धिशील बीज का उपयोग करकेप्रति थ्रेड के एक उदाहरण को आलसी रूप से तत्काल करता है।

+0

मुझे इतना संदेह था कि एमएसडीएन की जांच के बाद भी मुझे यकीन नहीं था। मैं आपका लेख भी देखूंगा। धन्यवाद। – dandan78

+0

जॉन स्कीट [MiscUtil.StaticRandom] (http://www.yoda.arachsys.com/csharp/miscutil/) भी देखें। – Brian

4

रैंडम एक छद्म-यादृच्छिक संख्या जनरेटर है और इसे कई कॉल के लिए एक ही परिणाम लौटने से रोकने में कुछ भी नहीं है। आखिरकार ऐसा होने की संभावना है। उल्लेख नहीं है कि documentation के अनुसार:

किसी भी इंस्टेंस सदस्यों को थ्रेड सुरक्षित होने की गारंटी नहीं है।

तो आपको एकाधिक धागे से Next विधि को कॉल नहीं करना चाहिए।

1

आपका उदाहरण कोड केवल _Random प्रति धागे का उपयोग दिखाता है। मान लीजिए यह मामला है, आप मुख्य for लूप में यादृच्छिक संख्या भी उत्पन्न कर सकते हैं और पैरामीटर के रूप में प्रत्येक थ्रेड में यादृच्छिक संख्या पास कर सकते हैं।

for (int i = 0; i < no_threads; ++i) 
{ 
     var thread = new Thread(new ThreadStart(Send)); 
     thread.Start(_Random.Next(999999)); 
} 

और फिर पैरामीटर स्वीकार करने के लिए अपने धागा समारोह को संशोधित:

static void Send(int device_id) 
{ 
    ... 
    //int device_id = _Random.Next(999999); 
    ... 
} 
संबंधित मुद्दे