2013-07-20 3 views

उत्तर

8

array आपके प्रोग्राम परिवर्तनीय है जब आप << जैसे ऑपरेशन को लागू करते हैं। यह तीन चरणों में होता है:

  • चर को पहले एक सीपीयू रजिस्टर में कॉपी किया गया है।
  • सीपीयू कम्प्यूटेशंस करता है।
  • सीपीयू परिणाम को परिवर्तनीय स्मृति में वापस लिखता है।

तो यह उच्च स्तरीय एकल ऑपरेशन तीन चरणों में किया जाता है। इन चरणों के बीच, थ्रेड-संदर्भ स्विचिंग के कारण, अन्य थ्रेड चर के समान (पुराने) मान को पढ़ सकता है। यही कारण है कि यह एक परमाणु ऑपरेशन नहीं है।

+1

आप पढ़ना चाहेंगे: [** रुबी में परमाणु संचालन **] (http://moonbase.rydia.net/mental/blog/programming/atomic-operations-in-ruby.html) –

+1

क्या आपने पढ़ा इस? [जोर्ग की सितंबर 2011 की टिप्पणी के साथ अपडेट किया गया] (http://stackoverflow.com/questions/56087/does-ruby-have-real-multithreading/57802#57802) –

+0

@theTinMan बहुत धन्यवाद! मेरी अंग्रेजी खराब है :(लेकिन मुझे सावधानी से ध्यान दिया गया है कि आपके उत्तर में संपादित किया गया है और मैं अगले उत्तर में सुधार करूंगा। धन्यवाद! –

1

क्योंकि रूबी एक बहुत ही उच्च स्तर की भाषा है, कुछ भी नहीं है:

http://www.jstorimer.com/pages/ruby-core-classes-arent-thread-safe

इसके अलावा आप इस मणि में रुचि हो सकती ओएस स्तर पर वास्तव में परमाणु। ओएस स्तर (ओएस आश्रित) पर केवल बहुत ही सरल असेंबली ऑपरेशंस परमाणु हैं, और प्रत्येक रूबी ऑपरेशन, यहां तक ​​कि एक साधारण 1 + 1 सैकड़ों या हजारों असेंबली निर्देशों के अनुरूप होता है, जैसे विधि लुकअप, कचरा संग्रह, ऑब्जेक्ट प्रारंभिकता, स्कोप गणना आदि।

यदि आपको परमाणु संचालन करने की आवश्यकता है, तो म्यूटेक्स का उपयोग करें।

6

यदि आपके पास एक ही सरणी तक पहुंचने वाले एकाधिक थ्रेड हैं, तो रूबी के अंतर्निहित Queue कक्षा का उपयोग करें। यह अच्छी तरह से निर्माता और उपभोक्ताओं को संभालती है।

require 'thread' 

queue = Queue.new 

producer = Thread.new do 
    5.times do |i| 
    sleep rand(i) # simulate expense 
    queue << i 
    puts "#{i} produced" 
    end 
end 

consumer = Thread.new do 
    5.times do |i| 
    value = queue.pop 
    sleep rand(i/2) # simulate expense 
    puts "consumed #{value}" 
    end 
end 

consumer.join 
5

असल में एमआरआई (Matz के रूबी कार्यान्वयन) जीआईएल (ग्लोबल दुभाषिया लॉक) का उपयोग कर किसी भी शुद्ध सी समारोह परमाणु बनाता है:

इस दस्तावेज़ से उदाहरण है।

चूंकि Array#<< एमआरआई में शुद्ध सी-कोड के रूप में लागू किया गया है, यह ऑपरेशन परमाणु होगा। लेकिन ध्यान दें कि यह केवल एमआरआई पर लागू होता है। JRuby पर यह मामला नहीं है।

पूरी तरह से समझने के लिए क्या चल रहा है मेरा सुझाव है पर आप इन दो लेख पढ़ने, जो सब कुछ बताते हैं बहुत अच्छी तरह से:

Nobody Understands the GIL
Nobody Understands the GIL - part 2

0

बस @Linuxios और @TheTinMan के बंद riffing: उच्च स्तरीय सामान्य रूप से भाषा (एचएलएल) संचालन परमाणु नहीं हैं। परमाणुता (आमतौर पर) एकल-थ्रेडेड कार्यक्रमों में कोई मुद्दा नहीं है।बहु-थ्रेडेड प्रोग्राम्स में, आपको (प्रोग्रामर) को एक एचएलएल ऑपरेशन की तुलना में बहुत अधिक ग्रैन्युलरिटी पर इसके बारे में तर्क करना पड़ता है, इसलिए व्यक्तिगत एचएलएल ऑपरेशंस जो परमाणु हैं, वास्तव में आपको बहुत मदद नहीं करते हैं। फ्लिप पक्ष पर, हालांकि एचएलएल ऑपरेशन परमाणु बनाने से — कम से कम आधुनिक हार्डवेयर — स्थिर (बाइनरी आकार) और गतिशील (निष्पादन समय) ओवरहेड में कम से कम कुछ मशीन निर्देश लेते हैं। इससे भी बदतर, स्पष्ट परमाणुता सभी अनुकूलन को बहुत अक्षम करता है क्योंकि संकलक परमाणु संचालन में निर्देश नहीं ले सकते हैं। कोई वास्तविक लाभ + महत्वपूर्ण लागत = गैर स्टार्टर।

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