2013-01-31 59 views
23

कहें कि हमारे पास दो धागे हैं, एक लूप में एक बूल पढ़ रहा है और दूसरा इसे निश्चित समय पर टॉगल कर सकता है। व्यक्तिगत रूप से मुझे लगता है कि यह परमाणु होना चाहिए क्योंकिसी ++ में 1 बाइट है और आप आंशिक रूप से बाइट्स को पढ़/लिखते नहीं हैं लेकिन मैं 100% निश्चित होना चाहता हूं।क्या एक बूल पढ़ने/लिखने का ऑपरेशन x86 पर परमाणु नहीं हो सकता है?

तो हाँ या नहीं?

संपादित:

भविष्य में संदर्भ के लिए इसके अलावा

, एक ही int लागू होता है?

+0

अंतर्निहित वास्तुकला के शब्द आकार से कम कुछ भी नहीं है * परमाणु * और * कम कुशल * संभव से भी? –

+0

http://stackoverflow.com/questions/8037289/is-mutex-required-for-1-byte-shared- स्मृति से पता चलता है कि यह गैर-परमाणु है। –

+0

http://stackoverflow.com/questions/8517969/is-this-the-correct-way-to-atomically-read-and-write-a-bool सुझाव देता है कि यह "अधिकांश मशीनों में परमाणु" है। –

उत्तर

14

यह सब इस बात पर निर्भर करता है कि आप वास्तव में "परमाणु" शब्द से क्या मतलब रखते हैं।

क्या आपका मतलब है "अंतिम मान एक बार में अपडेट किया जाएगा" (हाँ, x86 पर जो निश्चित रूप से बाइट मान के लिए गारंटीकृत है - और कम से कम 64 बिट्स तक सही ढंग से गठबंधन मूल्य), या "अगर मैंने इसे सेट किया है सत्य (या झूठा) के लिए, कोई अन्य थ्रेड इसे सेट करने के बाद एक अलग मान नहीं पढ़ेगा "(यह इतना निश्चित नहीं है - आपको इसकी गारंटी देने के लिए" लॉक "उपसर्ग की आवश्यकता है)।

+0

"अगर मैं इसे सत्य (या झूठा) पर सेट करता हूं, तो कोई अन्य धागा इसे सेट करने के बाद एक अलग मान नहीं पढ़ेगा"। मुझे लगता है कि सवाल बहुत स्पष्ट है। यह बाद की व्याख्या परमाणुता के साथ कुछ भी नहीं है। – jberryman

+2

@ जेबरीमैन: समस्या कैश के साथ-साथ स्मृति के पढ़ने को अनुकूलित करने वाले संकलक के साथ आता है। कुछ थ्रेड में 'बी = झूठा; 'गारंटी नहीं देता है कि अन्य सभी धागे,' if (b) ... 'के अगले मामले में,' बी 'गलत होगा। इसके लिए यह आवश्यक है कि कंपाइलर ने 'b' तक पहुंच को 'tmp = b में अनुकूलित नहीं किया है; ... अगर (टीएमपी) ... '[जहां' tmp' एक रजिस्टर है]। थ्रेड के अंदर कोड के आधार पर, ऐसी परिस्थितियां होती हैं जब एक कंपाइलर ऐसा करेगा। –

6

x86 केवल शब्द-संरेखित रीड और शब्द आकार के लिखने की गारंटी देता है। यह स्पष्ट रूप से परमाणु होने तक, किसी अन्य परिचालन की गारंटी नहीं देता है। इसके अलावा, ज़ाहिर है, आपको वास्तव में प्रासंगिक पाठों को लिखने और लिखने के लिए अपने कंपाइलर को मनाने की ज़रूरत है।

52

तीन अलग-अलग समस्या नहीं है कि सी ++ 11 पते में "परमाणु" प्रकार:

  1. फाड़: एक पढ़ने या लिखने कई बस चक्र शामिल है, और एक धागा स्विच आपरेशन के बीच में होता है ; यह गलत मान उत्पन्न कर सकता है।

  2. कैश समेकन: एक थ्रेड से एक लेखन अपने प्रोसेसर के कैश को अपडेट करता है, लेकिन वैश्विक स्मृति अपडेट नहीं करता है; एक अलग थ्रेड से पढ़ा गया वैश्विक स्मृति पढ़ता है, और अन्य प्रोसेसर के कैश में अद्यतन मान नहीं देखता है।

  3. कंपाइलर अनुकूलन: संकलक इस धारणा के तहत पढ़ता है और लिखता है कि मान किसी दूसरे धागे से नहीं पहुंचाया जाता है, जिसके परिणामस्वरूप अराजकता होती है।

std::atomic<bool> का उपयोग सुनिश्चित करता है कि इन तीनों में से सभी मुद्दों को सही ढंग से प्रबंधित किया जाता है। std::atomic<bool> का उपयोग न करने से आपको अनुमान लगाया जा सकता है, सर्वोत्तम रूप से, गैर-पोर्टेबल कोड।

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

  • कोई संबंधित समस्या नहीं^_^