2010-04-02 14 views
8

मुझे यकीन है कि यह एक बहुत ही सरल सवाल है, लेकिन मैं इसे चारों ओर मेरे सिर नहीं मिल सकता है कहने के लिए शर्मिंदा हूं:सरल स्काला अभिनेता सवाल

मैं स्काला में मूल्यों की एक सूची है। मैं समांतर में प्रत्येक मान के साथ कुछ (बाहरी) कॉल करने के लिए उपयोग कलाकारों का उपयोग करना चाहता हूं।

मैं तब तक इंतजार करना चाहता हूं जब तक कि सभी मान संसाधित नहीं हो जाते हैं, और फिर आगे बढ़ें।

कोई साझा मूल्य संशोधित नहीं किया जा रहा है।

कोई भी सलाह दे सकता है?

धन्यवाद

उत्तर

17

वहाँ स्काला में एक अभिनेता-का उपयोग कर वर्ग के लिए ठीक किया जाता है इस तरह की समस्या: वायदा। इस समस्या को हल किया जाएगा:

// This assigns futures that will execute in parallel 
// In the example, the computation is performed by the "process" function 
val tasks = list map (value => scala.actors.Futures.future { process(value) }) 

// The result of a future may be extracted with the apply() method, which 
// will block if the result is not ready. 
// Since we do want to block until all results are ready, we can call apply() 
// directly instead of using a method such as Futures.awaitAll() 
val results = tasks map (future => future.apply()) 

वहां आप जाते हैं। बस कि।

+1

यह बहुत आसान है, इसमें कुछ गड़बड़ होना चाहिए ;-) बहुत अच्छा लगता है, धन्यवाद। – 7zark7

+0

@ 7zark7 हाँ, मुझे वह रास्ता भी लगा। :-) यह संकलित करता है, हालांकि, और मुझे नहीं लगता कि मैंने कोई विशेष गलती की है। सुनिश्चित करें कि 'प्रक्रिया' अपवाद नहीं फेंकती है, और जागरूक रहें कि यदि आप I/O करने जा रहे हैं, तो यह आपके साथ काम करने के साथ ही काम नहीं करेगा, क्योंकि चल रहे वायदा केवल थ्रेड को प्रतीक्षा कर देगा। –

+1

यह काम करता है। असल में, मैंने यह सुनिश्चित करने के लिए परीक्षण किया कि यह अभिनेता शैली के रूप में कुशलतापूर्वक मल्टीटास्क करता है (मैं उत्सुक था, क्योंकि मैंने पहले ऐसा नहीं किया था या 'फ्यूचर्स' स्रोत कोड में देखा था) और ऐसा करता है। –

9

कार्यकर्ताओं बनाएँ और उन्हें !! का उपयोग कर भविष्य के लिए पूछना; फिर परिणामों को पढ़ें (जिसे गणना की जाएगी और वे तैयार होने के समानांतर में आते हैं; फिर आप उनका उपयोग कर सकते हैं)। उदाहरण के लिए:

object Example { 
    import scala.actors._ 
    class Worker extends Actor { 
    def act() { Actor.loop { react { 
     case s: String => reply(s.length) 
     case _ => exit() 
    }}} 
    } 
    def main(args: Array[String]) { 
    val arguments = args.toList 
    val workers = arguments.map(_ => (new Worker).start) 
    val futures = for ((w,a) <- workers zip arguments) yield w !! a 
    val results = futures.map(f => f() match { 
     case i: Int => i 
     case _ => throw new Exception("Whoops--didn't expect to get that!") 
    }) 
    println(results) 
    workers.foreach(_ ! None) 
    } 
} 

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

और हम यकीन है कि यह काम करता है बनाने के लिए इस बाहर की कोशिश कर सकते हैं:

scala> Example.main(Array("This","is","a","test")) 
List(4, 2, 1, 4) 
+0

बहुत बहुत धन्यवाद - मुझे लगता है कि भविष्य में वायदा और उपयोग का उल्लेख पूरी तरह से याद नहीं आया !! इससे पहले। – 7zark7

+0

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

+0

@Mog - 'f()' गणना का परिणाम प्राप्त होता है (जब तक यह उपलब्ध न हो) ब्लॉक। 'मैच' इसलिए है क्योंकि अभिनेताओं द्वारा भेजे गए संदेशों को' किसी भी 'के रूप में टाइप किया जाता है - हम एक इंट बैक प्राप्त करने की उम्मीद कर रहे हैं (इसलिए हम इसकी तलाश करते हैं), लेकिन अगर हम कुछ अप्रत्याशित कारणों के लिए कुछ और प्राप्त करते हैं, तो हम अपवाद फेंकते हैं । –

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