Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala调度器工作者-参与者模式_Scala_Actor_Dispatcher - Fatal编程技术网

Scala调度器工作者-参与者模式

Scala调度器工作者-参与者模式,scala,actor,dispatcher,Scala,Actor,Dispatcher,我正在尝试使用标准的Scala.actors包为Scala设计一个dispatcher-worker-actor模式 dispatcher从java.util.concurrent.LinkedBlockingQueue接收工作,并将其发送给工作者参与者进行处理。当所有工作完成后,调度员应该告诉每个工人退出,然后也应该退出。下面是我提出的代码,但当所有工作都完成时它会挂起(我认为dispatcher队列中有挂起的'GiveMeWork消息): import java.util.concurren

我正在尝试使用标准的Scala.actors包为Scala设计一个dispatcher-worker-actor模式

dispatcher从
java.util.concurrent.LinkedBlockingQueue
接收工作,并将其发送给工作者参与者进行处理。当所有工作完成后,调度员应该告诉每个工人退出,然后也应该退出。下面是我提出的代码,但当所有工作都完成时它会挂起(我认为dispatcher队列中有挂起的
'GiveMeWork
消息):

import java.util.concurrent.LinkedBlockingQueue
导入scala.actors.Actor
对象调度器
扩展演员{
println(“已创建的调度程序”)
def法案(){
val workers=(1到4).map(id=>(新Worker(id)).start()
环路{
反应{
案例'GiveMeWork=>
//println(“要求工作的工人”)
val(时间,i)=工作队列。take()
如果(时间==0){
println(“退出时间”)
工人。每小时(!?0升)
}否则{
println(“到达调度员:i:+i+”调度时间:+
时间+”,经过:“+(System.nanoTime()-time))
发送者!时间到了
}
案例'Quit=>
println(“被告知退出”)
寄件人下班
退出()
}
}
}
}
类工作者(id:Int)
扩展演员{
println(“创建的工人(“+id+”))
变量作业=0
def法案(){
调度员给了我工作
环路{
反应{
案例时间:长=>
如果(时间==0){
println(“工人(“+id+”)完成“+jobs+”jobs”)
寄件人下班
退出()
}否则{
println(“到达工作区(“+id+”):调度时间:+
时间+”,经过:“+(System.nanoTime()-time))
线程睡眠(id)
职位+=1
调度员给了我工作
}
}
}
}
}
val workQueue=newlinkedblockingqueue[(长,Int)](1000)
Dispatcher.start()
对于(i有一场比赛:

val (time, i) = workQueue.take()
所有工作都已完成,包括
workQueue.put((0L,0))
,因此它将永远等待

同时使用不同类型的并发是个坏主意

调度员可以将任务限制通知任务源:

import scala.actors.{Actor, OutputChannel}
import scala.collection.mutable.Queue

case class Task(time: Long, i: Int)
case object GiveMeWork
case object Quit
case object OffDuty

object Dispatcher extends Actor {
  println("Dispatcher created")

  def act() {
    val workers = (1 to 4).map(id => (new Worker(id)).start())
    val waitingWorkers = Queue[OutputChannel[Any]](workers: _*)
    val tasks = Queue[Task]()
    var workSender: Option[OutputChannel[Any]] = None

    loop {
      react {
        case GiveMeWork =>
          if (!tasks.isEmpty) sender ! tasks.dequeue()
          else waitingWorkers enqueue sender

          workSender map { _ ! GiveMeWork }
          workSender = None
        case t: Task =>
          if (!waitingWorkers.isEmpty) waitingWorkers.dequeue() ! t
          else tasks enqueue t

          if (tasks.length < 1000) sender ! GiveMeWork
          else workSender = Some(sender)
        case Quit =>
          println("Told to quit")
          workers.foreach{ _ ! Quit }
          sender ! OffDuty
          exit()
      }
    }
  }
}

class Worker(id: Int)
extends Actor {
  var jobs = 0

  def act() {
    loop {
      react {
        case t: Task =>
          Thread.sleep(id)
          jobs += 1
          Dispatcher ! GiveMeWork
        case Quit =>
          println("Worker(" + id + ") completed " + jobs + " jobs")
          sender ! OffDuty
          exit()
      }
    }
  }
}

Dispatcher.start()

for (i <- 0 until 5000) {
  Thread.sleep(1)
  Dispatcher !? Task(System.nanoTime(), i)
}

println("Telling Dispatcher to quit")
Dispatcher !? Quit
import scala.actors.{Actor,OutputChannel}
导入scala.collection.mutable.Queue
案例类任务(时间:长,i:Int)
案例对象给我的工作
案例对象退出
案件对象下班
对象调度器扩展了Actor{
println(“已创建的调度程序”)
def法案(){
val workers=(1到4).map(id=>(新Worker(id)).start()
val waitingWorkers=队列[OutputChannel[Any]](工作人员:*)
val tasks=队列[任务]()
var workSender:选项[OutputChannel[Any]]=None
环路{
反应{
case GiveMeWork=>
如果(!tasks.isEmpty)发件人!tasks.dequeue()
else waitingWorkers排队发送程序
工作区映射{{uu!GiveMeWork}
工作区=无
案例t:Task=>
如果(!waitingWorkers.isEmpty)waitingWorkers.dequeue()!t
其他任务排队
如果(tasks.length<1000)发送者!给我工作
else workSender=Some(发送方)
案例退出=>
println(“被告知退出”)
工人们,请退出
发送者!下班
退出()
}
}
}
}
类工作者(id:Int)
扩展演员{
变量作业=0
def法案(){
环路{
反应{
案例t:Task=>
线程睡眠(id)
职位+=1
调度员!给我工作
案例退出=>
println(“工人(“+id+”)完成“+jobs+”jobs”)
发送者!下班
退出()
}
}
}
}
Dispatcher.start()

例如(我不喜欢使用LinkedBlockingQueue,但我需要限制等待执行的最大进程数。当我在实际代码中使用此模式时,由于生成工作的方法(目录递归下降)而导致内存不足错误,添加文件的速度比处理文件的速度快。对于如何纯粹使用参与者来完成此操作,有何建议?
import scala.actors.{Actor, OutputChannel}
import scala.collection.mutable.Queue

case class Task(time: Long, i: Int)
case object GiveMeWork
case object Quit
case object OffDuty

object Dispatcher extends Actor {
  println("Dispatcher created")

  def act() {
    val workers = (1 to 4).map(id => (new Worker(id)).start())
    val waitingWorkers = Queue[OutputChannel[Any]](workers: _*)
    val tasks = Queue[Task]()
    var workSender: Option[OutputChannel[Any]] = None

    loop {
      react {
        case GiveMeWork =>
          if (!tasks.isEmpty) sender ! tasks.dequeue()
          else waitingWorkers enqueue sender

          workSender map { _ ! GiveMeWork }
          workSender = None
        case t: Task =>
          if (!waitingWorkers.isEmpty) waitingWorkers.dequeue() ! t
          else tasks enqueue t

          if (tasks.length < 1000) sender ! GiveMeWork
          else workSender = Some(sender)
        case Quit =>
          println("Told to quit")
          workers.foreach{ _ ! Quit }
          sender ! OffDuty
          exit()
      }
    }
  }
}

class Worker(id: Int)
extends Actor {
  var jobs = 0

  def act() {
    loop {
      react {
        case t: Task =>
          Thread.sleep(id)
          jobs += 1
          Dispatcher ! GiveMeWork
        case Quit =>
          println("Worker(" + id + ") completed " + jobs + " jobs")
          sender ! OffDuty
          exit()
      }
    }
  }
}

Dispatcher.start()

for (i <- 0 until 5000) {
  Thread.sleep(1)
  Dispatcher !? Task(System.nanoTime(), i)
}

println("Telling Dispatcher to quit")
Dispatcher !? Quit