2011-08-16 11 views
7

मेरे पास एक अभिभावक और कार्यकर्ता धागा है जो एक बूल ध्वज और एक std :: वेक्टर साझा करता है। माता-पिता केवल पढ़ता है (यानी, बूल पढ़ता है या my_vector.empty() को कॉल करता है); कार्यकर्ता केवल लिखता है।एक पाठक। एक लेखक म्यूटेक्स और परमाणु-निर्मित के बारे में कुछ सामान्य प्रश्न

मेरे सवालों का:

  • मैं bool ध्वज की रक्षा म्युटेक्स की जरूरत है?

  • क्या मैं कह सकता हूं कि सभी बूल पढ़ने/लिखने स्वाभाविक रूप से परमाणु संचालन हैं? यदि आप हां या नहीं कहते हैं, तो आपको अपनी जानकारी कहां से मिली?

  • मैंने हाल ही में GCC Atomic-builtin के बारे में सुना है। क्या मैं म्यूटक्स का उपयोग किए बिना अपने ध्वज को परमाणु पढ़ने/लिखने के लिए इनका उपयोग कर सकता हूं? अंतर क्या है? मैं समझता हूं कि परमाणु बिल्टिन मशीन कोड पर उबालते हैं, लेकिन म्यूटेक्स भी सीपीयू के मेमोरी बाधा निर्देशों को उबालते हैं? लोग म्यूटेक्स को "ओएस-स्तरीय" निर्माण क्यों कहते हैं?

  • क्या मुझे अपने std :: vector की रक्षा करने के लिए mutex की आवश्यकता है? याद रखें कि कार्यकर्ता धागा इस वेक्टर को पॉप्युलेट करता है, जबकि माता-पिता केवल उस पर खाली() कहते हैं (यानी, केवल इसे पढ़ता है)

  • मुझे विश्वास नहीं है कि बूल या वेक्टर के लिए म्यूटेक्स सुरक्षा आवश्यक है। मैं निम्नानुसार तर्कसंगत हूं, "ठीक है, अगर मैंने अद्यतन स्मृति को अपडेट करने से ठीक पहले पढ़ा है .. यह अभी भी ठीक है, मुझे अगली बार अद्यतन मूल्य मिलेगा। अधिक महत्वपूर्ण बात यह है कि मुझे नहीं पता कि लेखक को क्यों अवरुद्ध किया जाना चाहिए पढ़ना पढ़ रहा है, क्योंकि बाद में, पाठक केवल पढ़ रहा है! "

अगर कोई मुझे सही दिशा में इंगित कर सकता है, तो यह बहुत अच्छा होगा। मैं जीसीसी 4.3, और इंटेल x86 32-बिट पर हूं। बहुत बहुत धन्यवाद!

उत्तर

13

क्या मुझे बूल ध्वज की रक्षा करने के लिए म्यूटक्स की आवश्यकता है?

जरूरी नहीं कि एक परमाणु निर्देश होगा। atomic instruction मेरा मतलब है कि एक कंपाइलर आंतरिक फ़ंक्शन है कि ए) कंपाइलर रीडरिंग/ऑप्टिमाइज़ेशन को रोकता है और बी) परमाणु पढ़ने/लिखने और सी में परिणाम) सीपीयू के बीच दृश्यता सुनिश्चित करने के लिए एक उपयुक्त मेमोरी बाड़ जारी करता है (मौजूदा x86 CPUs के लिए जरूरी नहीं है जो MESI cache coherency protocol को नियोजित करता है)। gcc atomic builtins के समान।

क्या मैं कह सकता हूं कि सभी बूल पढ़ने/लिखने स्वाभाविक रूप से परमाणु संचालन हैं? यदि आप हां या नहीं कहते हैं, तो आपको अपनी जानकारी कहां से मिली?

सीपीयू पर निर्भर करता है। इंटेल सीपीयू के लिए - हाँ। Intel® 64 and IA-32 Architectures Software Developer's Manuals देखें।

मैंने हाल ही में जीसीसी परमाणु-निर्मित के बारे में सुना है।क्या मैं म्यूटक्स का उपयोग किए बिना अपने ध्वज को परमाणु पढ़ने/लिखने के लिए इनका उपयोग कर सकता हूं? अंतर क्या है? मैं समझता हूं कि परमाणु बिल्टिन मशीन कोड पर उबालते हैं, लेकिन म्यूटेक्स भी सीपीयू के मेमोरी बाधा निर्देशों को उबालते हैं? लोग म्यूटेक्स को "ओएस-स्तरीय" निर्माण क्यों कहते हैं?

परमाणुओं और म्यूटेक्स के बीच का अंतर यह है कि उत्तरार्द्ध म्यूटेक्स जारी होने तक प्रतीक्षा थ्रेड को सो सकता है। परमाणुओं के साथ आप केवल व्यस्त-स्पिन कर सकते हैं।

क्या मुझे अपने std :: vector की रक्षा करने के लिए mutex की आवश्यकता है? याद रखें कि कार्यकर्ता धागा इस वेक्टर को पॉप्युलेट करता है, जबकि माता-पिता केवल उस पर खाली() कहते हैं (यानी, केवल इसे पढ़ता है)

आप करते हैं।

मुझे विश्वास नहीं है कि बूल या वेक्टर के लिए म्यूटेक्स सुरक्षा आवश्यक है। मैं निम्नानुसार तर्कसंगत हूं, "ठीक है, अगर मैंने अद्यतन स्मृति को अपडेट करने से ठीक पहले पढ़ा है .. यह अभी भी ठीक है, मुझे अगली बार अद्यतन मूल्य मिलेगा। अधिक महत्वपूर्ण बात यह है कि मुझे नहीं पता कि लेखक को क्यों अवरुद्ध किया जाना चाहिए पढ़ना पढ़ रहा है, क्योंकि बाद में, पाठक केवल पढ़ रहा है! "

कार्यान्वयन के आधार पर vector.empty() पढ़ने दो बफर शुरू/अंत संकेत और घटाकर या उनकी तुलना भी शामिल हो सकता है, इसलिए इस बात की संभावना है कि आप एक के बिना एक सूचक का एक नया संस्करण और एक दूसरे के एक पुराने संस्करण पढ़ है म्युटेक्स। आश्चर्यजनक व्यवहार हो सकता है।

+1

के साथ 'bool' के संबंध में, वह निश्चित रूप से यह सुनिश्चित करने के लिए उपयोग वास्तव में तब होता है जब वह सोचता है कि यह करता है कुछ की जरूरत है। यदि उसके पास एक कंपाइलर है जो 'std :: परमाणु <>' का समर्थन करता है, तो वह पर्याप्त होना चाहिए; अन्यथा, उसे किसी भी प्रकार की सिंक्रनाइज़ेशन तंत्र की आवश्यकता होती है, या यह सुनिश्चित करने के कुछ अन्य साधन हैं कि आवश्यक बाड़, आदि मौजूद हैं। –

+0

भी ध्यान रखें कि 'std :: vector' अपने पैरों के नीचे से उसकी सामग्री को स्थानांतरित हो सकता है जब यह बड़ा बफर के लिए फिर से आवंटित करने के लिए की जरूरत है। इस बिंदु पर उपभोक्ता 'हटाएं'-एड मेमोरी पढ़ रहा हो सकता है। –

+0

@Maxim: मैं एक स्पष्टीकरण कृपया की जरूरत है, bools पर इंटेल के मैनुअल संचालन के अनुसार स्वाभाविक परमाणु हैं, फिर भी आप अपनी पहली जबाब है कि "एक परमाणु अनुदेश करना होगा" में कहते हैं। क्या आप विरोधाभास कर रहे हैं? या, क्या आप कह रहे हैं कि मुझे सुरक्षित पक्ष पर होना चाहिए और एक परमाणु निर्मित का उपयोग करना चाहिए, मेरा कोड कभी भी गैर-इंटेल सिस्टम पर चलता है? – Kostolma

2

उत्तर:

  1. आप bool (या उस बात के लिए किसी अन्य चर) एक ही समय में दो या अधिक धागे से पर संचालित कर देने की संभावना है की रक्षा के लिए की आवश्यकता होगी। आप या तो इसे म्यूटेक्स के साथ या बूल पर काम करके कर सकते हैं।
  2. बूल पढ़ता है और बूल लिखता है परमाणु संचालन हो सकता है, लेकिन दो अनुक्रमिक संचालन निश्चित रूप से नहीं हैं (उदाहरण के लिए, एक पढ़ा और फिर एक लिखना)। इस पर और अधिक।
  3. परमाणु निर्मित उपरोक्त समस्या का समाधान प्रदान करते हैं: एक चर में एक चर को पढ़ने और लिखने की क्षमता जिसे किसी अन्य थ्रेड द्वारा बाधित नहीं किया जा सकता है। यह ऑपरेशन परमाणु बनाता है।
  4. यदि आप अपने 'म्यूटेक्स' के रूप में बूल ध्वज का उपयोग कर रहे हैं (यानी, केवल धागा जो बूल ध्वज को सत्य में सेट करता है, वेक्टर को संशोधित करने की अनुमति है) तो आप ठीक हैं। पारस्परिक बहिष्कार बुलियन द्वारा प्रबंधित किया जाता है, और जब तक आप परमाणु संचालन का उपयोग करके बूल को संशोधित कर रहे हैं, तो आपको पूरा सेट होना चाहिए।
  5. इस उत्तर के लिए, मुझे एक उदाहरण का उपयोग करते हैं: एक बहु-क्रम वातावरण में

 

bool    flag(false); 
std::vector<char> my_vector; 

while (true) 
{ 
    if (flag == false) // check to see if the mutex is owned 
    { 
     flag = true; // obtain ownership of the flag (the mutex) 

     // manipulate the vector 

     flag = false; // release ownership of the flag 
    } 
} 

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

ध्यान दें कि ध्वज को झूठी पर वापस सेट करना एक परमाणु ऑपरेशन नहीं है क्योंकि आप यह उदाहरण केवल इसे संशोधित करने के अधिकारों के साथ ही हैं।

मोटे (पढ़ें: अपरीक्षित) समाधान कुछ लग सकता है जैसे:

bool    flag(false); 
std::vector<char> my_vector; 

while (true) 
{ 
    // check to see if the mutex is owned and obtain ownership if possible 
    if (__sync_bool_compare_and_swap(&flag, false, true)) 
    { 
     // manipulate the vector 

     flag = false; // release ownership of the flag 
    } 
} 

परमाणु builtin के लिए दस्तावेज़ में लिखा है:

"bool" संस्करण TRUE देता तुलना सफल हुआ और नया पत्र लिखा गया था।

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

0

मेरे पास आपके पूरे प्रश्न का उत्तर देने की विशेषज्ञता नहीं है लेकिन आपके अंतिम बुलेट डिफ़ॉल्ट रूप से गैर-परमाणु हैं, जिन मामलों में गलत है।

एक संदर्भ स्विच हो सकता है कहीं भी, पाठक संदर्भ प्राप्त कर सकते हैं पढ़ने के माध्यम से बीच-बीच में बंद कर, लेखक में बंद कर प्राप्त कर सकते हैं और पूर्ण लिखने हैं, और तब पाठक अपने पढ़ने खत्म होगा। पाठक न तो पहला मान, न ही दूसरा मूल्य, बल्कि संभावित रूप से कुछ जंगली गलत मध्यवर्ती मूल्य देखेंगे।

2

सी ++ 11 मानकों की दृष्टि से, आप एक म्युटेक्स साथ bool की रक्षा, या वैकल्पिक रूप std::atomic<bool> उपयोग करना होगा। यहां तक ​​कि जब आप सुनिश्चित करें कि आपके bool पढ़ सकते हैं और वैसे भी atomically लिखा है कर रहे हैं, वहाँ अभी भी मौका है कि संकलक दूर अनुकूलन कर सकते हैं यह करने के लिए accesses क्योंकि यह अन्य सूत्र है कि संभावित उस तक पहुँच सकता है के बारे में पता नहीं है।

अगर किसी कारण से आपको अपने मंच के प्रदर्शन की नवीनतम बिट की ज़रूरत है, तो "इंटेल 64 और आईए -32 आर्किटेक्चर सॉफ्टवेयर डेवलपर मैनुअल" पढ़ने पर विचार करें, जो आपको बताएगा कि चीजें आपके आर्किटेक्चर पर हुड के तहत कैसे काम करती हैं। लेकिन निश्चित रूप से, यह आपके कार्यक्रम को अयोग्य बना देगा।

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