0

我正在与 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”来等待来自主线程的消息。

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

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

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

在“react”和“receive”之间是否存在某些东西,其中执行会像“receive”一样离开块,但要避免像“react”那样创建新线程?或者也许我可以通过其他方式将线程数限制为 1?

A-Posteriori 我读过关于 scala continuations 的文章,但这需要太多的代码更改(你会同意 scala continuations 使用起来有点复杂......)。

谢谢

4

1 回答 1

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

于 2012-10-07T08:19:33.773 回答