Tüm oyuncular temel olarak başlık altındaki bir programlayıcı tarafından çalıştırılan iş parçacıklarıdır. Zamanlayıcı, çekirdek sayınıza kabaca bağlanan aktörleri çalıştırmak için bir iş parçacığı havuzu oluşturur. Bu sadece size yürütmek ve Scala gerisini bırakmak gerekir görevin başına bir aktör oluşturmak anlamına gelir:
burada dezavantaj görevlerin sayısının, her görev için bir iş parçacığı oluşturma maliyetine bağlı olduğu
for(i <- 1 to 20) {
actor {
print(i);
Thread.sleep(1000);
}
}
may Java'da threadlar çok ucuz olmadığı için oldukça pahalı olun.
şey gibi olurdu mesaj yoluyla kendilerine görevleri dağıtmak ardından işçi aktörlerin sınırlı bir havuz oluşturmak ve basit bir yolu: Biz oyuncuların çokluğu oluşturmak istiyorum
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
}
nedeni tek aktör süreçler nedeniyle Bir kerede sadece bir mesaj (yani görev), görevleriniz için paralellik elde etmek için birden fazla oluşturmanız gerekir.
Bir yan not: Varsayılan zamanlayıcı, G/Ç ilişkili görevler söz konusu olduğunda, özellikle de bu durumda iş parçacığı havuzunun boyutunu değiştirmek isteyeceğinizden özellikle önem kazanır. Bu konuda ayrıntılara giren iki iyi blog yazısı: Explore the Scheduling of Scala Actors ve Scala actors thread pool pitfall.
Bununla birlikte, Akka, Aktörlerle daha gelişmiş iş akışları için araçlar sağlayan bir Aktör çerçevesidir ve gerçek bir uygulamada kullanacağım şey budur. Eğer daha fazla bilgi için dokümanlar here kontrol edebilirsiniz böylece
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(..)
}
Sen, Yük Dengeleme farklı (CyclicIterator yuvarlak robin dağılımıdır) sahip olabilir: Burada görev uygulamakla (yerine rastgele yerine) bir yük dengeleme.
Scala Aktörleri veya paralel koleksiyonları denediniz mi? İş yükünü zaten farklı CPU'larda dağıtabilirler. Daha fazla kontrole ihtiyacınız varsa Akka'ya bir göz atabilirsiniz. – Fabian