2012-09-13 16 views
6

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

क्या सुझाव दिया गया था कि एक अभिनेता संदेश प्राप्त कर रहा है यह एक आंतरिक काउंटर बढ़ाने के लिए काउंटर को थ्रेडसेफ तरीके से बढ़ाएगा। कि दो अपडेट संदेश एक साथ संसाधित नहीं किए जाएंगे, और इसलिए कोई भी दो संदेश काउंटर को एक ही समय में अपडेट करने का प्रयास नहीं कर सकता था।

एक अभिनेता में एक काउंटर विशेषता "साझा स्थिति" की तरह लगता है।

क्या यह वाकई सच है कि ऐसा ऑपरेशन पूरी तरह से थ्रेडसेफ होगा? यदि हां, तो अभिनेता कुछ कुशल तरीके से एकाधिक कोर मशीनों का उपयोग कैसे करता है? एक अभिनेता बहु थ्रेड कैसे किया जाता है?

यदि नहीं, तो कुछ सिंक्रनाइज़/अस्थिर चर की आवश्यकता के बिना थ्रेडसेफ तरीके से संदेशों को गिनने के लिए उपयुक्त आदर्श तरीका क्या है?

उत्तर

8

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

कतार पूरी होने से बचने के लिए, यह महत्वपूर्ण है कि संदेश प्रसंस्करण (react, receive, आदि) जितना संभव हो सके छोटा हो।लंबे समय से चल रहे कार्यों के एक अन्य अभिनेता को हस्तांतरित कर दिया जाना चाहिए:

1. Actor A receives a message M from sender S 
2. A spawns a new actor C 
3. A sends (S, f(M)) to C 
4. In parallel: 
4a. A starts processing the next message. 
4b. C does the long-running or dangerous (IO) task, 
    When finished, sends the result to S, 
    and C terminates. 

प्रक्रिया में कुछ विकल्प:

  • सी ए जो एस
  • एक को यहां पर अग्रेषित करने के लिए (S, result) भेजता वापस एक मानचित्रण रहता ActorRef C => (Sender S, Message M)so in case it sees C fail, यह एक नए अभिनेता के साथ एम प्रसंस्करण पुनः प्रयास कर सकते हैं।

तो संक्षिप्त करने के लिए, एक अभिनेता के मल्टी-थ्रेडेड इस हद तक कि कई ग्राहकों विभिन्न धागे से यह कई संदेश भेज सकते हैं करने के लिए है, और यह गारंटी है कि अभिनेता इन सभी संदेशों क्रमानुसार पर कार्रवाई करेंगे (हालांकि आदेश हो सकता है विभिन्न गैर-अत्यधिक सख्त बाधाओं के अधीन)।

ध्यान दें कि जब एक्टर्स react कोड may be executed on various threads, समय की एक भी भी बिंदु में यह एक एकल दिया धागे पर निष्पादित किया जाता है केवल (आप के रूप में अनुसूचक फिट देखता है यह है कि अभिनेता धागे से कूदता थ्रेड को यह चित्र सकता है, लेकिन एक तकनीकी विवरण है)। नोट: आंतरिक स्थिति को अभी भी सिंक्रनाइज़ेशन की आवश्यकता नहीं है, क्योंकि प्रोसेसिंग संदेशों के बीच अभिनेता guarantee happens-before semantics

समानांतर में काम कर रहे कई अभिनेता होने के समानांतरता प्राप्त होती है, आमतौर पर supervisor hierarchies या balancing workload बनाते हैं।

ध्यान दें कि यदि आपको केवल समवर्ती/असीमित कंप्यूटेशंस की आवश्यकता है, लेकिन आपके पास वैश्विक स्थिति, Futures are a better composing और आसान अवधारणा से छुटकारा नहीं मिल सकता है या नहीं। स्केल स्रोत कोड के सूचक के लिए

+0

यह एक महान स्पष्टीकरण है, धन्यवाद! – Brian

+0

अच्छा जवाब। मैं यह जोड़ूंगा कि एक अभिनेता की प्रतिक्रियाएं अलग-अलग धागे पर चल सकती हैं (और इस प्रकार 'सामान्य रूप से स्मृति मेसेज मुद्दों के अधीन रहेंगी), आपको वास्तव में अभिनेता के राज्य तक पहुंच को सिंक्रनाइज़ करने की आवश्यकता नहीं है। ऐसा इसलिए है क्योंकि एक अभिनेता को निष्पादित करने से पहले अभिनेता ढांचा पहले से ही ऐसा करता है। Http://stackoverflow.com/questions/1031167/should-my-scala-actors-properties-be-marked-volatile –

+0

देखें कि यह मदद करता है। रेजीस: धन्यवाद, टेक्स्ट को और सटीक होने के लिए अपडेट किया गया। – ron

6

"एक अभिनेता" बहुप्रचारित नहीं है, लेकिन अभिनेता प्रणाली आमतौर पर है। प्रत्येक अभिनेता एक समय में केवल एक ही क्रिया निष्पादित करता है, लेकिन जब कई अभिनेता होते हैं, तो प्रत्येक समानांतर में अपने संबंधित encapsulated राज्य पर काम कर सकते हैं। एक काउंटर विशेषता साझा परिवर्तनीय स्थिति नहीं है यदि इसे कलाकारों के बीच साझा नहीं किया गया है।

अपने प्रश्न अभिनेता प्रणाली के कार्यान्वयन, कि भिन्न होता है और आमतौर पर विन्यास योग्य है, यानि कि डिफ़ॉल्ट स्काला अभिनेताओं या तो एकल लड़ी या एक धागा पूल पर या का उपयोग कर जावा ForkJoin कार्यों को चलाने के लिए विन्यस्त किया जा सकता के बारे में है। मुझे scala.actors स्रोत बहुत पठनीय लगता है, इसलिए यदि आप समझना चाहते हैं कि क्या हो रहा है, तो मैं एक नज़र रखने की अनुशंसा करता हूं।

+0

+1। यह अच्छी तरह से अवधारणा को दिखाता है। – sourcedelica

2

आप गिनती करने के लिए एक अलग अभिनेता का उपयोग कर सकते हैं। जब एक अभिनेता को संदेश मिलता है, तो यह एक (सिंगलटन) गिनती अभिनेता को एक संदेश भेज सकता है। इस तरह आप कई कार्यकर्ता अभिनेता हो सकते हैं और अभी भी संदेशों की गिनती कर सकते हैं।

अक्का में Agents नामक कुछ है जो इस संदर्भ में उपयोगी हो सकता है।

val counter = Agent(0) 
counter send (_ + 1) 

http://doc.akka.io/docs/akka/2.0.2/scala/agents.html

+0

इस उपयोग के मामले में एक एजेंट दर्जी बना है। थ्रेडेडनेस और सिंक्रनाइज़ेशन के मामले में वे लिखने के लिए एक्टर्स और एटमिकएक्स के लिए अभिनेताओं की तरह काम करते हैं। – sourcedelica