हां, वे वही चर साझा करते हैं। यह थ्रेड का एक प्रमुख तत्व है और केवल पढ़ने के संदर्भ में ठीक है, लेकिन यदि वे किसी भी चर को लिखते हैं, तो आपको Mutex
और synchronize
धागे का उपयोग करने की आवश्यकता है, इसलिए केवल किसी भी समय किसी एक चर को बदल सकता है । कभी-कभी वे एक ऐसी विधि का आह्वान कर सकते हैं जो अप्रत्यक्ष रूप से डेटा को बदलता है, इसलिए आपको यह तय करने से पहले सिस्टम को पूरी तरह से जानना होगा कि आपको सिंक्रनाइज़ करने की आवश्यकता है या नहीं।
आपके दूसरे प्रश्न के लिए, यदि मैं समझता हूं कि आप क्या पूछ रहे हैं, तो उनके पास अलग-अलग स्टैक फ्रेम हैं, लेकिन वे अभी भी स्मृति में समान डेटा साझा कर रहे हैं।
स्पष्ट, निम्न उदाहरण में, स्थानीय चर zip
, एक से अधिक थ्रेड द्वारा साझा के बाद से यह (सूत्र, गुंजाइश परिवर्तन नहीं करते वे सिर्फ निष्पादन की एक अलग, समानांतर थ्रेड प्रारंभ वर्तमान क्षेत्र में परिभाषित किया गया है वर्तमान दायरे में)।
zip = 42
t = Thread.new do
zip += 1
end
t.join
puts zip # => 43
यहां शामिल होने से मुझे बचाता है, लेकिन स्पष्ट रूप से धागे में कोई बात नहीं है, अगर मैं वहां रहता हूं। अगर मैं निम्न करने के लिए थे यह खतरनाक होगा:
zip = 42
t = Thread.new do
zip += 1
end
zip += 1
puts zip # => either 43 or 44, who knows?
है ऐसा इसलिए है क्योंकि आप मूल रूप से दो धागे दोनों एक ही समय में zip
को संशोधित करने की कोशिश कर रहा है। जब आप उपरोक्त में नेटवर्क संसाधनों का उपयोग कर रहे हैं, या संख्या बढ़ाना आदि यह ध्यान देने योग्य हो जाता है।
निम्न उदाहरण में, हालांकि, स्थानीय चर zip
एक पूरी तरह से नया दायरे के अंदर बनाई गई है, इसलिए दो धागे वास्तव में एक ही समय में एक ही चर के लिए लिख नहीं हैं:
def foo
zip = 42
zip += 1 # => 43, in both threads
end
Thread.new do
foo
end
foo
वहाँ दो समांतर ढेर प्रबंधित किए जा रहे हैं, प्रत्येक foo
विधि के अंदर अपने स्वयं के स्थानीय चर के साथ।
निम्नलिखित कोड है, तथापि, खतरनाक है:
@zip = 42 # somewhere else
def foo
@zip += 1
end
Thread.new do
foo
end
foo
puts @zip # => either 43 or 44, who knows?
ऐसा इसलिए है क्योंकि उदाहरण चर @zip
foo
समारोह के दायरे के बाहर से पहुंचा है, इसलिए दोनों धागे एक ही समय में यह पहुँच रहे हैं।
वेरिएबल को बदलने वाले कोड के अनुभागों के आस-पास ध्यान से रखे गए म्यूटेक्स (ताले) का उपयोग करके 'दो थ्रेड एक ही समय में एक ही डेटा को बदलने' की इन समस्याओं का समाधान किया जाता है।म्यूटेक्स से पहले बनाए गए धागे बनाए जाते हैं, क्योंकि म्यूटेक्स के मामले में, यह (डिज़ाइन द्वारा) महत्वपूर्ण है कि दोनों धागे एक ही म्यूटेक्स तक पहुंच जाएं, ताकि यह पता चल सके कि यह लॉक है या नहीं।
# somewhere else...
@mutex = Mutex.new
@zip = 42
def foo
@mutex.synchronize do
@foo += 1
end
end
Thread.new do
foo
end
foo
puts @zip # => 44, for sure!
हैं जब निष्पादन के प्रवाह Mutex#synchronize
लाइन तक पहुँच जाता है, यह म्युटेक्स लॉक करने के लिए कोशिश करता है। यदि सफल हो, तो यह ब्लॉक में प्रवेश करता है और निष्पादन जारी रखता है। एक बार ब्लॉक खत्म होने के बाद, म्यूटेक्स फिर से अनलॉक हो जाता है। यदि म्यूटेक्स पहले ही लॉक हो चुका है, तो धागा तब तक इंतजार कर रहा है जब तक कि यह फिर से मुक्त न हो जाए ... प्रभावी रूप से यह एक दरवाजे की तरह है कि केवल एक ही व्यक्ति एक समय में चल सकता है।
मुझे आशा है कि यह चीजों को साफ़ कर देगा।
क्या आप केवल पढ़ने के लिए संदर्भ का उदाहरण दे सकते हैं? अगर foo एक स्थानीय चर बनाता है, तो उसे इसे कुछ असाइन करना होगा? –
जो मैंने यहां पढ़ा है: "थ्रेड वैरिएबल" विषय के तहत http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_threads.html अलग-अलग लगता है। या मैं सो रहा हूँ। – alk
आह, मैंने गलत समझा। यदि foo फ़ंक्शन स्थानीय चर बनाता है, तो यह ठीक है। यदि यह एक आवृत्ति चर बनाता है, हालांकि, जिसे अन्य धागे द्वारा एक्सेस किया जा सकता है, तो इसे म्यूटेक्स का उपयोग करना चाहिए। "केवल पढ़ने के लिए", मेरा मतलब यह है कि कोई आवृत्ति चर/वैश्विक चर संशोधित नहीं होते हैं। स्थानीय चर ठीक हैं ... वे वर्तमान धागे से संबंधित हैं। – d11wtq