从理论上讲,使用Scala Actor Framework可以像JDK 7的Fork-Join框架一样进行一种异步的分治计算吗?如果是这样,我怎么能用框架表达FJ问题 - 例如,教程mergesort概念?我们欢迎代码小贴士.
我的模拟是使用actor和Scala 2.8-Snapshot.在Java JRE 1.5中它运行良好 - 所有40个齿轮(演员)同时工作.使用Java JRE 1.6只有3个齿轮同时工作.我使用和不使用GUI进行测试:两者都给出相同的结果.
我在GUI上的模拟可以在github上找到:http://github.com/pmeiclx/scala_gear_simulation
也许你还记得我与演员的第一个问题.在解决了这些问题后,我为模拟做了一个GUI,我得到了这种新的"奇怪"行为.
这是没有GUI的代码:
package ch.clx.actorversions
import actors.Actor
import actors.Actor._
import collection.mutable.ListBuffer
case class ReceivedSpeed(gear: Gear)
case object StartSync
case class SyncGear(controller: GearController, syncSpeed: Int)
object ActorVersion {
def main(args:Array[String]) = {
println("[App] start with creating gears")
val gearList = new ListBuffer[Gear]()
for (i <- 0 until 100) {
gearList += new Gear(i)
}
val gearController = new GearController(gearList)
gearController.start()
gearController ! StartSync
}
}
/**
* CONTROLLER …Run Code Online (Sandbox Code Playgroud) 每当我读到关于使用synchronizedScala的作者通常提的是演员,而应使用(此举例).虽然我大致了解演员是如何工作的,但我真的很想看到Actors的一个例子用于替换Java的synchronized方法修饰符(我的意思是它的Scala等价物 - synchronized块)在一段代码中.例如,修改数据结构的内部结构会很高兴.
这是演员的好用还是被误导了?
我正在修补Akka并需要一些建议如何实现我想到的具体内容.我想有一个演员,我可以发送DownloadFile(URI, File)消息并下载它.由于这可以并行,我不想一个接一个地下载文件但是有并发下载限制.
什么是用Akka模拟这样的东西的预定方式?其他想到的事情是:如果某个"工人"演员因某种原因去世,会发生什么?如何重试下载?等等
我知道这是一个非常大的问题,但我希望有人花时间回答它!谢谢!
我是Akka的新手,在参考手册中找不到答案.
假设我们有远程actor分布在3台机器(A,B,C)的集群中,其中一个actor存在于每台机器上,而其他actor则有actorRef到另外两台机器,即:
Machine A:
A (real actor)
-> B (ref)
-> C (ref)
Machine B:
-> A (ref)
B (real actor)
-> C (ref)
Machine C:
-> A (ref)
-> B (ref)
C (real actor)
Run Code Online (Sandbox Code Playgroud)
Actor A执行以下代码:
bRef ! msg1
bRef ! msg2
Run Code Online (Sandbox Code Playgroud)
Actor B在消息处理程序中执行以下代码:
case msg1 =>
cRef ! msg3
aRef ! msg4
Run Code Online (Sandbox Code Playgroud)
Actor C在消息处理程序中执行以下代码:
case msg3 =>
aRef ! msg5
Run Code Online (Sandbox Code Playgroud)
我可以做出以下假设(如果有的话):
演员B在获得msg2之前得到msg1
演员A在获得msg4之前获得msg5
而后续问题可能导致了解上述内容:是否发送了消息!运营商是通过网络真正异步还是等到接收邮箱获得它?即行
bRef ! msg1
Run Code Online (Sandbox Code Playgroud)
阻止,直到演员B在其邮箱中获取消息,或者它是否产生处理传递并继续执行的线程
bRef ! msg2
Run Code Online (Sandbox Code Playgroud)
在它甚至知道演员B得到msg1之前?
我一直在努力回答是否有一个标准的Scala函数用于运行超时的块?,如果在Future中抛出异常,则会遇到问题.
def runWithTimeout[T](timeoutMs: Long)(f: => T) : Option[T] = {
awaitAll(timeoutMs, future(f)).head.asInstanceOf[Option[T]]
}
Run Code Online (Sandbox Code Playgroud)
以便
runWithTimeout(50) { "result" } should equal (Some("result"))
runWithTimeout(50) { Thread.sleep(100); "result" } should equal (None)
Run Code Online (Sandbox Code Playgroud)
但是如果我在我的块中抛出一个异常它不会泄漏,但是被吞下 - 所以下面的代码失败了"..没有抛出异常"
intercept[Exception] {
runWithTimeout(50) { throw new Exception("deliberate") }
}.getMessage should equal("deliberate")
Run Code Online (Sandbox Code Playgroud)
Syserr有一条带有消息的堆栈跟踪
<function0>: caught java.lang.Exception: deliberate
Run Code Online (Sandbox Code Playgroud)
但我无法找到Scala运行时中打印的位置.
除了在另一个块中包装f以捕获异常并在抛出时传播它们,有没有办法说服awaitAll和/或Future抛出?
虽然Scala演员被描述为轻量级,但Akka演员更是如此,显然有一些使用它们的开销.
所以我的问题是,与Actors并行的最小工作单元是什么(假设它可以并行化)?如果存在潜在的延迟或者存在大量繁重的计算,它是否值得?
我正在寻找一个可以轻松应用于日常工作的一般经验法则.
编辑:答案至今让我意识到,我很感兴趣,也许是真正的逆我原来问的问题.所以:
假设用actor构造我的程序非常合适,因此不会产生额外的开发开销(或者甚至比非actor的实现产生更少的开发开销),但是它执行的工作单元非常小 - 是否存在使用演员在性能方面会有什么损害,应该避免哪些?
我有一个actor,它创建一个子actor来执行一些冗长的计算.
问题是子actor的初始化需要几秒钟,并且父actor发送给它之间的子节点的所有消息都被创建并被完全初始化.
这是我正在使用的代码的逻辑:
class ChildActor extends Actor {
val tagger = IntializeTagger(...) // this takes a few seconds to complete
def receive = {
case Tag(text) => sender ! tagger.tag(text)
case "hello" => println("Hello")
case _ => println("Unknown message")
}
}
class ParentActor extends Actor {
val child = context.ActorOf(Props[ChildActor], name = "childactor")
// the below two messages seem to get lost
child ! "hello"
child ! Tag("This is my sample text")
def receive = {
...
}
}
Run Code Online (Sandbox Code Playgroud)
我怎么能解决这个问题?是否可以让父actor等到孩子完全初始化?我将使用带有路由的子actor,可能还有远程actor系统. …
假设我们有以下目标:
\n所以具体的问题是:我们如何才能使 Swift actor 遵守协议,同时保持隔离?
\nprotocol Zippity {\n func foo()\n}\n\nactor Zappity: Zippity {\n func foo() {} // Doesn\'t compile\n}\nRun Code Online (Sandbox Code Playgroud)\n我可以用 \xe2\x80\xa6 编译它
\nactor Zappity: Zippity {\n nonisolated func foo() {}\n}\nRun Code Online (Sandbox Code Playgroud)\n\xe2\x80\xa6 但这似乎违背了目的。我还尝试声明接口方法async,但也无法编译。
我可以想到几种合理的解决方法,包括组合、nonisolated async调用独立方法的方法等,但想看看是否有我遗漏的东西。
在并行处理项目列表时,是否有充分理由增加Futures(vs parallel collection)的复杂性?
List(...).par.foreach(x=>longRunningAction(x))
Run Code Online (Sandbox Code Playgroud)
VS
Future.traverse(List(...)) (x=>Future(longRunningAction(x)))
Run Code Online (Sandbox Code Playgroud)