2012-02-09 17 views
7

संभव डुप्लिकेट तक पहुँचने:
Are C# arrays thread safe?एकाधिक सूत्र एक ही बहु-आयामी सरणी

मैं अब 10 महीने के लिए प्रोग्रामिंग किया गया है सी #। अब मैं बहु-थ्रेडिंग सीख रहा हूं और अच्छी तरह से काम कर रहा हूं। मैं बहु आयाम सरणी

string[,] test = new string[5, 13]; 

जैसे मैं धागे तरीकों कि ऊपर सरणी के अंदर विभिन्न निर्देशांक के लिए अपने आउटपुट बचत अंत बुला होता है। किसी अन्य थ्रेड के समान स्थान पर किसी एक थ्रेड लेखन के बिना।

तो thread1test[1,10] को लिख सकते हैं, लेकिन कोई अन्य धागा कभी test[1,10]

मेरा प्रश्न है करने के लिए लिखेंगे: मैं अपने सरणी की तरह वस्तुओं पर ताले उपयोग के बारे में पढ़ा है, मैं ताले के बारे में बिल्कुल भी चिंता करने की क्या ज़रूरत है भले ही मेरे थ्रेड एक ही समय में परीक्षण सरणी तक पहुंच सकते हैं लेकिन कभी भी समान समन्वय (स्मृति स्थान) पर नहीं लिखते?

अभी तक मेरे परीक्षण में मुझे कोई समस्या नहीं है, लेकिन अगर कोई मुझसे ज्यादा अनुभवी जानता है तो मुझे समस्या हो सकती है तो मैं उपयोग ताले में देखूंगा।

+1

नहीं, आपको समझाया परिदृश्य में ताले की जरूरत नहीं है। लेकिन मुझे लगता है कि आप किसी बिंदु पर डेटा पढ़ रहे हैं? क्या आप पढ़ना शुरू करने से पहले अपने सभी धागे समाप्त होने तक प्रतीक्षा करते हैं? – Douglas

+1

यदि आप ताले का उपयोग नहीं करते हैं, तो यह सुनिश्चित करने के लिए कि सभी धागे के पास 'ताजा' डेटा तक पहुंच हो, पढ़ने के लिए शुरू होने से पहले मेमोरी बाधा ('Thread.MemoryBarrier()' को कॉल करके) को याद करने की अनुशंसा की जाएगी। [अनब्लॉकिंग सिंक्रनाइज़ेशन] (http://www.albahari.com/threading/part4.aspx) इस अवधारणा के बारे में एक महान स्पष्टीकरण है। – Douglas

+0

धन्यवाद, धागे एक मास्टर थ्रेड से उत्पन्न होते हैं, वे केवल सरणी में डेटा लिखते हैं, फिर एक बार जब वे सब खत्म हो जाते हैं, तो RunWorker मास्टर थ्रेड को समाप्त कर देता है, सरणी पढ़ता है। इसलिए मुझे लगता है कि मैं सुरक्षित हूं, स्पष्टीकरण के लिए धन्यवाद। –

उत्तर

7

यदि आप यह सुनिश्चित कर सकते हैं कि कोई भी दो धागे कभी भी उसी तत्व को पढ़ने या लिखने का प्रयास नहीं करेंगे तो आपको लॉकिंग करने की आवश्यकता नहीं है, और यदि आप लॉकिंग जोड़ते हैं तो आप अपना कोड धीमा कर देंगे।

हालांकि आपको यह समझाने के लिए उचित टिप्पणियां जोड़ने के लिए समय लेना चाहिए कि, (और संभवतः क्यों) कोई फ्रेड कभी भी उसी तत्व तक पहुंचने के लिए नहीं पहुंचता है, जो कि जिम फेल ने अपने उत्तर में वर्णित भविष्य की समस्याओं से बचने के लिए किया है।

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

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

0

आपको यह सुनिश्चित करने के लिए लॉक स्टेटमेंट का उपयोग करना चाहिए कि आपकी डेटा ऑब्जेक्ट थ्रेड-सुरक्षित है। यह अब काम कर रहा है, लेकिन बाद में (विशेष रूप से जब/यदि कोड अपडेट किया गया है) तो आप (या आपकी प्रतिलिपि) भ्रामक दौड़-स्थिति या डेटा-भ्रष्टाचार कीड़े में भाग सकते हैं। Check out this article on the MSDN website। लॉक स्टेटमेंट का उपयोग करने के तरीके पर इसका एक अच्छा उदाहरण है।

1

इस बारे में सावधान रहना एक बात है कि यदि आप एक कोर प्रोसेसर के साथ परीक्षण कर रहे हैं, तो सब कुछ ठीक काम कर सकता है, लेकिन जैसे ही आप बहु-कोर प्रोसेसर पर चलते हैं, आप एक साझा टुकड़े को मारने वाले धागे के साथ समस्याओं में भाग लेते हैं एक ही समय में स्मृति।

बस सुरक्षित होने के लिए, यदि दो धागे वास्तव में आपके बहु-सरणी को सीधे संशोधित कर रहे हैं, तो आपको लॉकिंग सिस्टम को लागू करने की आवश्यकता है। This answer in StackOverflow लॉकिंग का एक अच्छा उदाहरण है।

-1

ताले केवल एक साथ पहुंच को रोकने के लिए हैं। तो यदि आप इसे अन्य तरीकों से गारंटी देते हैं, तो आपको कोई ताले की आवश्यकता नहीं है।

पीएस मुझे लगता है कि आपने प्रत्येक थ्रेड को प्रत्येक सरणी तत्व में असाइन किया है, है ना?

+4

साथ-साथ पहुंच केवल एक मुद्दा है यदि एक साथ संचालन * mutating * और * non-atomic * दोनों होते हैं। लेकिन ताले परमाणु संचालन में गैर-परमाणु संचालन करने से अधिक करते हैं; वे * पूर्ण बाड़ स्मृति बाधाओं * भी परिचय। मान लीजिए कि कोड के लेखक चतुराई से गारंटी देते हैं कि स्मृति के दो गैर-परमाणु पढ़ने/लिखने को अंतःस्थापित नहीं किया जाएगा; यह बहुत अच्छा है, लेकिन ऐसा करने से अपर्याप्त हो सकता है। ** ऐसा करना गारंटी नहीं है कि किसी भी दो धागे में सभी डेटा के सभी उत्परिवर्तनों का एक * लगातार * दृश्य है **। –

+0

उन्होंने प्रत्येक थ्रेड कार्यों को अपने स्वयं के सरणी तत्व के साथ बताया। आदेश यहां कोई फर्क नहीं पड़ता। – Dims

+2

आप मेरे बिंदु का पालन नहीं कर रहे हैं। मान लीजिए थ्रेड अल्फा 123 को सरणी स्थान पर लिखता है 2. मान लें कि थ्रेड ब्रावो को स्थान 2 को पढ़ने की गारंटी नहीं है जब तक कि धागा अल्फा को कुछ गैर-लॉकिंग समाधान के माध्यम से उत्परिवर्तन नहीं किया जाता है। क्या गारंटी है कि जब थ्रेड ब्रावो स्थान 2 पढ़ता है, तो उसे उस स्थान पर 123 मिल जाता है? कोई भी नहीं, कुछ भी नहीं! थ्रेड ब्रावो थ्रेड अल्फा की तुलना में एक अलग प्रोसेसर पर चल रहा था, और ** ब्रावो के प्रोसेसर को सरणी के मेमोरी पेज को कैश किया जा सकता था। ** ब्रावो के सीपीयू को कैश को अमान्य करने के लिए क्या मजबूर करता है? *कुछ भी तो नहीं*। –

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