मैं फ़ंक्शन InterlockedExchange पर आया और यह सोच रहा था कि मुझे इस फ़ंक्शन का उपयोग कब करना चाहिए। मेरी राय में, एक x86 प्रोसेसर पर 32 बिट मान सेट करना हमेशा परमाणु होना चाहिए?
मामले में जहां मैं फ़ंक्शन का उपयोग करना चाहता हूं, नया मान पुराने मान पर निर्भर नहीं है (यह एक वृद्धि ऑपरेशन नहीं है)। आपको एक उदाहरण प्रदान कर सके जहां इस पद्धति अनिवार्य है (मैं InterlockedCompareExchange के लिए नहीं देख रहा हूँ)Win32 InterlockedExchange फ़ंक्शन का उपयोग कब किया जाना चाहिए?
उत्तर
एक बहु-प्रोसेसर या बहु-कोर मशीन में प्रत्येक कोर में इसका अपना कैश होता है - इसलिए प्रत्येक कोर में सिस्टम मेमोरी की सामग्री का प्रत्येक संभावित रूप से अलग "दृश्य" होता है।
धागा तुल्यकालन तंत्र http://blogs.msdn.com/oldnewthing/archive/2008/10/03/8969397.aspx पर कोर के बीच सिंक्रनाइज़ किया जा रहा है, अधिक जानकारी देखने के लिए की देखभाल या अधिग्रहण के लिए गूगल और जारी अर्थ विज्ञान
InterlockedExchange
दोनों एक लिखने और पढ़ने है - यह पिछले मान देता है।
यह सुनिश्चित करना आवश्यक है कि एक और थ्रेड आपके द्वारा किए जाने के बाद एक अलग मूल्य नहीं लिखता। उदाहरण के लिए, कहें कि आप एक चर को बढ़ाने की कोशिश कर रहे हैं। आप मान पढ़ सकते हैं, 1 जोड़ सकते हैं, फिर नया मान InterlockedExchange
के साथ सेट कर सकते हैं। InterlockedExchange
द्वारा लौटाए गए मान को आपके द्वारा मूल रूप से पढ़ने वाले मान से मेल खाना चाहिए, अन्यथा किसी अन्य थ्रेड ने इसे एक ही समय में बढ़ाया है, और आपको चारों ओर लूप करने और फिर से प्रयास करने की आवश्यकता है।
इस मामले में, मैं InterlockedCompareExchange का उपयोग करूंगा, क्योंकि जांच करें कि मान अभी भी मूल था, विधि पहले से ही किया गया है। – EFrank
या सिर्फ इंटरलाक्डइनक्रिएशन –
साथ ही साथ नया मान लिखना, InterlockedExchange
भी पिछले मान को पढ़ता है और देता है; यह पूरा ऑपरेशन परमाणु है। यह lock-free algorithms के लिए उपयोगी है।
(संयोग से, 32-बिट राईट परमाणु होने की गारंटी नहीं कर रहे हैं। मामले पर विचार करें जहां लिखने असंरेखित है और एक कैश सीमा फैली उदाहरण के लिए,।)
यह प्रोसेसर पर चल रहे सॉफ़्टवेयर के दृष्टिकोण से परमाणु होगा, लेकिन बस पर बैठे हार्डवेयर के दृष्टिकोण से नहीं। –
क्या यह किसी अन्य कोर पर चल रहे सॉफ़्टवेयर के पीओवी से परमाणु होगा? एक पृष्ठ सीमा को पार करते हुए और एक गलती ट्रिगर करने वाले लेखन के बारे में क्या? पिछले कुछ वर्षों से मैंने निम्न स्तर के x86 कोडिंग किए हैं, अनुमान है कि मैं झूठ बोल सकता हूं:/ – moonshadow
स्थापना एक 32-बिट मूल्य परमाणु है, लेकिन केवल अगर आप एक शाब्दिक स्थापित कर रहे हैं।
mov eax,dword ptr [a]
mov dword ptr [b],eax
सैद्धांतिक रूप से वहाँ पहले और दूसरे आपरेशन के बीच कुछ रुकावट हो सकता है:
ख = 2 आपरेशन है।
और यदि कुछ बाधाएं होंगी, तो क्या होगा - इसमें थोड़ी देर लग जाएगी, लेकिन ईएक्स में मूल्य नहीं बदलेगा। इंटरलाक्ड एक्सचेंज का वास्तविक बिंदु यह है कि यह परमाणु पढ़ने और लिखना है। – Suma
फिर क्या? नरक। बाधा सिस्टम कॉल का कारण बन सकती है, सिस्टम एक संदर्भ स्विच को कॉल करता है और फिर कोई अन्य थ्रेड मान बदलता है। फिर ईएक्स बहाल किया जाता है और मूल्य फिर से बदल जाता है। संदर्भों की गणना करते समय रेस की स्थिति विशेष रूप से घातक होती है। कुछ थ्रेड मान में वृद्धि कर सकते हैं जबकि एक और धागा मान कम करता है, या दो धागे एक ही समय में इसे बढ़ा सकते हैं। वह ईएक्स बहाल किया गया समाधान समाधान नहीं है - इसकी समस्या है। –
और एक से अधिक CPU/core होने पर यह और भी बदतर हो जाता है। – SamB
एक मूल्य के लेखन डिफ़ॉल्ट रूप से परमाणु कभी नहीं है। जब आप एक चर के लिए एक मान लिखते हैं, तो कई मशीन निर्देश उत्पन्न होते हैं। आधुनिक, प्रीपेप्टिव ओएस के साथ, ओएस लिखने के व्यक्तिगत संचालन के बीच एक और धागे पर स्विच कर सकता है।
यह बहु-प्रोसेसर मशीनों पर और भी एक समस्या है, जहां एक ही समय में कई धागे निष्पादित हो सकते हैं, और एक ही स्मृति स्थान को एक साथ लिखने की कोशिश कर रहे हैं।
इंटरलॉक ऑपरेशन लिखने के लिए विशेष निर्देशों का उपयोग करके इस से बचें (x86 इस तरह की स्थिति के लिए समर्पित निर्देश हैं), जो एक निर्देश में पढ़ने-संशोधित-लेखन करते हैं। ये निर्देश सभी प्रोसेसर की मेमोरी बस को भी लॉक करते हैं, यह सुनिश्चित करने के लिए कि कोई अन्य निष्पादन थ्रेड एक ही समय में मूल्य पर लिख नहीं सकता है।
-1, गलत सादे गठबंधन लिखने x86 पर परमाणु हैं। – Johan
इंटरलाक्ड एक्सचेंज यह सुनिश्चित करता है कि एक चर का परिवर्तन और उसके मूल मूल्य की वापसी अन्य धागे से बाधित न हो।
तो, अगर 'i' एक पूर्णांक, ये कॉल (व्यक्तिगत रूप से लिया गया) InterlockedExchange की जरूरत नहीं है 'i' के आसपास है:
a = i;
i = 9;
i = a;
i = a + 9;
a = i + 9;
if(0 == i)
इन बयानों में से कोई भी की शुरूआती और अंतिम मूल्यों पर भरोसा करते हैं ' मैं'। लेकिन इन निम्नलिखित कॉल की ज़रूरत है InterlockedExchange चारों ओर 'i':
a = i++; //a = InterlockedExchange(&i, i + 1);
इसके बिना
, दो धागे यह एक ही कोड के माध्यम से चल 'मैं' 'एक' या करने के लिए आवंटित की एक ही मूल्य मिल सकता है 'एक' अप्रत्याशित रूप से छोड़ सकते हैं दो या अधिक संख्याएं।
if(0 == i++) //if(0 == InterlockedExchange(&i, i + 1))
दो धागे दोनों कोड को निष्पादित कर सकते हैं जो केवल एक बार होने वाला है।
आदि
गलत उदाहरण 'ए = इंटरलाक्ड एक्सचेंज (और i, i + 1); '।आपका 'i' अन्य CPU द्वारा' i + 1' और 'InterlockedExchange' के बीच बदला जा सकता है। – Fr0sT
वाह, इतने सारे विवादित उत्तर। कौन सही है, कौन गलत है, और कौन सी जानकारी भ्रामक है, के माध्यम से निकलना मुश्किल है।
मैं भी जवाब के बारे में अनिश्चित, यह देखते हुए ऊपर आधा जवाब हूँ, लेकिन मैं इसे इस तरह से काम करता है लगता है, मैं, गलत हो सकता है और यह पता लगाने के लिए दिलचस्प हो सकता है अगर मैं कर रहा हूँ:
- 32-बिट पढ़ें & लिखते हैं परमाणु हैं, लेकिन आपके कोड के आधार पर, इसका मतलब अधिक नहीं हो सकता है।
- गैर-गठबंधन पढ़ने/लिखने के बारे में चिंता न करें। 32-बिट वैरिएबल को सभी 32-बिट लिखने के लिए गठबंधन किया जाना चाहिए या मशीन पेज-दोष होना चाहिए।
- कैश किए गए पृष्ठ के अंत में लिखने के बारे में चिंता न करें, ऐसा नहीं हो सकता है।
- यदि आपको एक धागे पर लिखने की आवश्यकता है, और आप किसी अन्य धागे पर लिख रहे हैं, तो आपको इंटरलाक्ड एक्सचेंज का उपयोग करने की आवश्यकता है। यदि आप केवल एक थ्रेड पर मान पढ़ रहे हैं, और इसे किसी अन्य पर लिख रहे हैं, तो आपको इसका उपयोग करने की आवश्यकता नहीं है, लेकिन मल्टीथ्रेडिंग के कारण ये मान विचित्र रूप से हो सकते हैं।
-1 32-बिट्स वर्र्स को x86 पर गठबंधन करने की आवश्यकता नहीं है। और 32 बिट लिखते हैं x86 पर परमाणु, लेकिन कई अन्य आर्किटेक्चर पर नहीं। – Johan
- 1. Flask.g का उपयोग कब किया जाना चाहिए?
- 2. std :: nothrow कब उपयोग किया जाना चाहिए?
- 3. कब जोर देना चाहिए() का उपयोग किया जाना चाहिए?
- 4. कब [असेंबली: InternalsVisibleTo()] का उपयोग किया जाना चाहिए?
- 5. किसी वेब सेवा का उपयोग कब नहीं किया जाना चाहिए?
- 6. रणनीति पैटर्न का उपयोग कब और क्यों किया जाना चाहिए?
- 7. किसी स्मृतिदृश्य का उपयोग कब किया जाना चाहिए?
- 8. सी # में अस्थिर कीवर्ड का उपयोग कब किया जाना चाहिए?
- 9. आईफोन: नेटवर्क गतिविधि सूचक का उपयोग कब किया जाना चाहिए
- 10. डेटाबेस समानार्थी शब्द का उपयोग कब किया जाना चाहिए?
- 11. कब, कहां और कैसे कतारों का उपयोग किया जाना चाहिए?
- 12. कमजोर संदर्भों का उपयोग कब किया जाना चाहिए?
- 13. ईन्नोएम को कब आवंटित किया जाना चाहिए?
- 14. <%# ... %> और <%= ... %> कब उपयोग किया जाना चाहिए?
- 15. सुरक्षा एनोटेशन 'denyAll' कब उपयोग किया जाना चाहिए?
- 16. initWithFormat कब होगा: तर्क: उपयोग किया जाना चाहिए?
- 17. स्ट्रेस का उपयोग कैसे किया जाना चाहिए?
- 18. RedirectToRoute का उपयोग कैसे किया जाना चाहिए?
- 19. scala.util.parsing.ast.Binders का उपयोग कैसे किया जाना चाहिए?
- 20. ईएफ 4 में पीओसीओ का इस्तेमाल कब किया जाना चाहिए?
- 21. पूर्णांक को स्पष्ट रूप से कब निर्दिष्ट किया जाना चाहिए?
- 22. कथन का उपयोग करते समय उपयोग किया जाना चाहिए?
- 23. आधुनिक सी ++ में अपवादों का उपयोग कैसे किया जाना चाहिए?
- 24. सी ++ में बूल और बूल का उपयोग कब किया जाना चाहिए?
- 25. लंबे मतदान में session_write_close का उपयोग क्यों किया जाना चाहिए?
- 26. डेटाबेस इंडेक्स को पुनर्निर्मित कब किया जाना चाहिए?
- 27. कॉपी-लोकल को कब सही किया जाना चाहिए और यह कब नहीं होना चाहिए?
- 28. डेटा कब/डेटा में जाना चाहिए, और इसे/inst/extdata में कब जाना चाहिए?
- 29. एनकोडुरि का कभी भी उपयोग किया जाना चाहिए?
- 30. @Entity Pojos का परीक्षण किया जाना चाहिए?
कैश यहां माध्यमिक हैं। यहां तक कि अगर कोई कैश और सीपीयू मेमोरी से बात नहीं कर रहे थे तो भी सामान्य पढ़ना/लिखना अनुक्रम परमाणु नहीं है। – Suma