सभी कलाकार मूल रूप से धागे हैं जिन्हें हुड के नीचे शेड्यूलर द्वारा निष्पादित किया जाता है। शेड्यूलर आपके कोर के मोटे तौर पर बाध्य कलाकारों को निष्पादित करने के लिए एक थ्रेड पूल बनाता है। इसका मतलब यह है कि आप बस काम प्रति एक अभिनेता आप निष्पादित और स्काला के बाकी छोड़ने की जरूरत बना सकते हैं:
for(i <- 1 to 20) {
actor {
print(i);
Thread.sleep(1000);
}
}
नुकसान यहाँ कार्यों की संख्या, प्रत्येक कार्य के लिए एक धागा बनाने की लागत पर निर्भर करता है हो सकता है काफी महंगा हो क्योंकि जावा में धागे इतने सस्ते नहीं हैं।
कार्यकर्ता अभिनेताओं की एक घिरे पूल बनाने और उसके बाद संदेश के माध्यम से उन्हें कार्य वितरित होगा कुछ की तरह करने के लिए एक आसान तरीका:
import scala.actors.Actor._
val numWorkers = 4
val pool = (1 to numWorkers).map { i =>
actor {
loop {
react {
case x: String => println(x)
}
}
}
}
for(i <- 1 to 20) {
val r = (new util.Random).nextInt(numWorkers)
pool(r) ! "task "+i
}
कारण है कि हम कई अभिनेताओं का निर्माण करना चाहते है, क्योंकि एक भी अभिनेता प्रक्रियाओं आपके कार्यों के लिए समांतरता प्राप्त करने के लिए एक समय में केवल एक संदेश (यानी कार्य) आपको एकाधिक बनाने की आवश्यकता है।
एक साइड नोट: जब I/O बाध्य कार्यों की बात आती है तो डिफ़ॉल्ट शेड्यूलर विशेष रूप से महत्वपूर्ण हो जाता है, क्योंकि आप निश्चित रूप से उस मामले में थ्रेड पूल के आकार को बदलना चाहते हैं। इसके बारे में विवरण में जाने वाले दो अच्छे ब्लॉग पोस्ट हैं: Explore the Scheduling of Scala Actors और Scala actors thread pool pitfall।
इसके साथ, Akka एक अभिनेता ढांचा है जो अभिनेताओं के साथ अधिक उन्नत वर्कफ़्लोज़ के लिए टूल प्रदान करता है, और यही वह है जो मैं किसी भी वास्तविक एप्लिकेशन में उपयोग करता हूं।
import akka.actor.Actor
import Actor._
import akka.routing.{LoadBalancer, CyclicIterator}
class TaskHandler extends Actor {
def receive = {
case t: Task =>
// some computationally expensive thing
t.execute
case _ => println("default case is required in Akka...")
}
}
class TaskRouter(numWorkers: Int) extends Actor with LoadBalancer {
val workerPool = Vector.fill(numWorkers)(actorOf[TaskHandler].start())
val seq = new CyclicIterator(workerPool)
}
val router = actorOf(new TaskRouter(4)).start()
for(i <- 1 to 20) {
router ! Task(..)
}
आप लोड संतुलन के विभिन्न प्रकार (CyclicIterator राउंड-रोबिन वितरण है) हो सकता है तो आप अधिक जानकारी के लिए डॉक्स here जाँच कर सकते हैं: यहाँ एक लोड संतुलन कार्य प्रबंधक (बल्कि यादृच्छिक से) है।
स्रोत
2011-06-24 16:25:27
क्या आपने स्कैला अभिनेताओं या समांतर संग्रहों की कोशिश की है? वे पहले से ही विभिन्न सीपीयू पर वर्कलोड वितरित कर सकते हैं। अगर आपको अधिक नियंत्रण की आवश्यकता है तो आप अक्का में देख सकते हैं। – Fabian