scala actors vs线程和阻止IO

Li *_*oyi 19 concurrency multithreading scala actor

据我所知,actor基本上是在线程上实现的轻量级线程,在一小部分共享线程上运行许多actor.

鉴于这种情况,在actor中使用阻塞操作会阻塞底层线程.这不是一个正确性问题,因为actor库会根据需要产生更多线程(是吗?)但是最后你会遇到很多线程,从而否定了首先使用actor的好处.

鉴于此,当您需要执行此类IO操作时,演员如何工作?是否存在"actor-block"的操作,在让线程继续执行其他操作时暂停actor(就像阻塞操作在让CPU继续执行其他操作时暂停线程一样),或者是所有用CPS编写的链接,链接演员?或者演员根本不适合这种长期运行?

背景:我有经验编写多线程东西的经验,并且了解CPS /事件循环如何工作,但绝对没有与演员合作的经验,只想在高水平上了解他们如何适应,在我潜水之前进入代码.

Ant*_*era 2

这不是正确性问题,因为 Actor 库将根据需要生成更多线程(是吗?)

据我了解,这是不对的。参与者被阻止,向其发送另一条消息会导致该消息保留在参与者的邮箱中,直到该参与者可以receive发送或react发送该消息。

在《Scala 编程》(1) 中,明确指出 Actor 不应该阻塞。如果一个参与者需要做一些长时间运行的事情,它应该将工作传递给第二个参与者,以便主要参与者可以释放自己并从其邮箱中读取更多消息。一旦工作人员完成工作,它就可以将该事实发送回主要参与者,后者可以完成它必须做的任何事情。

由于工人也有邮箱,因此最终会出现几个工人忙着工作的情况。如果你没有足够的 CPU 来处理这个问题,他们的队列就会变得越来越大。最终,您可以使用远程参与者进行横向扩展。 在这种情况下, Akka可能更有用。

(1)《Scala 编程》(Odersky,第二版,2010 年)第 32.5 章

编辑:我发现了这个:

Actor 特征的调度程序方法可以被重写以返回 RessizedThreadPoolScheduler,它调整其线程池的大小,以避免由调用任意阻塞方法的 Actor 引起的饥饿。

找到它: http: //www.scala-lang.org/api/current/scala/actors/Actor.html

因此,这意味着根据您设置的调度程序实现,用于运行参与者的池可能会增加。当我说你错了时我错了:-) 答案的其余部分仍然成立。