Scala Actors - 使用带有接收的SingleThreadedScheduler

时间:2012-10-07 02:04:53

标签: scala scheduled-tasks generator actor

我正在与Scala Actors合作尝试实现一些调度算法。

调度程序接收两个函数,在计算过程中调用一些“交互”函数。例如:

def func1(x:Int, y:Int)(scheduler:MyScheduler):Int = {
   var z = 0
   if (scheduler.interact(1)) {
       return 7
   }
   z = x * y
   for (c <- 1 to 10) {
       if (scheduler.interact(z)) {
           return z
       }
       z = z * c
   }
   z
}

现在调度程序需要同时运行顺序两个函数,并且每当函数执行到达“交互”时,调度程序决定是让相同的函数继续还是暂停它并唤醒它其他功能计算。

您可以将其视为运行python生成器,使用调度程序决定每次调用哪个生成器的 next()

我使用Scala Actors实现了这一点 - 每个函数都在一个actor中执行,interact操作向主线程(调度程序)回复一些值,并调用“receive”来等待来自main的消息线程。

请注意,我不能使用“react”而不是“receive”,因为我需要执行从receive-block中断(并从“interaction”函数返回)。

然后我想通过使用SingleThreadedScheduler让我的演员总是在主线程上运行来改进实现。

然而,似乎与“react”不同,“receive”函数尝试创建一个阻止执行的新线程。

“react”和“receive”之间是否存在某些内容,其中执行会像“接收”一样离开块,但是避免创建像“react”这样的新线程? 或者我可以用其他方式将线程数限制为1?

A-Posteriori我读到了关于scala continuation的内容,但这需要更多的代码更改(并且你会同意scala continuation的使用有点复杂......)。

由于

1 个答案:

答案 0 :(得分:0)

这种挑战证明了演员模型并不总是正确的抽象。正如你所说,延续通常会使事情变得更复杂,对于那些阅读代码的人来说,甚至可能更加模糊。

我自己的偏好是找到一种方法来清楚地说明线程实际上要做什么。幸运的是,这可以使用优秀的JCSP API(来自UKC)。虽然这是一个Java API,但它在Scala中也可以正常工作,并且已经成熟且稳定(有一个Oxford Uni纯Scala项目,但这可能还不成熟)。 JCSP实现了Hoare的CSP,这是一种数学代数,但一旦你意识到它是由事件驱动的,它就很容易使用。演员可以很容易地在JCSP中建模,但反之亦然。

在您的应用程序中,您的调度程序将拥有自己的CS-Process(也称为Java线程),并将根据收到的事件确定自己的状态和生命周期。这允许它按顺序调用这两个函数,而不是同时重叠,而是成为更广泛的线程活动套件的一部分。

http://www.cs.kent.ac.uk/projects/ofa/jcsp/提供了背景材料。罐子在http://mvnrepository.com/artifact/org.codehaus.jcsp/jcsp