【发布时间】:2016-05-26 14:04:45
【问题描述】:
我正在学习 scala。我对actor和goroutine的区别感到很困惑。
众所周知,golang的并发单元是goroutine,并发模型在我看来是非常特殊和优雅的:
- CPU 绑定任务
运行时调度程序会尽最大努力抢占长时间运行的协程,例如函数调用时检查抢占,让长时间运行的协程不会占用系统线程太久
- 事件驱动调用
例如,在 Linux 上,可以通过 epoll 管理的所有类型的事件,例如socket connect,将产生 goroutine 并在稍后调用完成时恢复它。当 goroutine 屈服时,持有线程将被释放以处理下一个准备好的 goroutine
- cgo 调用
此类调用将独占一个系统线程,直到调用返回。
如何在 scala actor 中处理所有这些类型的调用?
scala 重用并依赖 JDK 来访问低级系统调用,对吗?例如网络套接字。一些高级库也在 scala 中被重用,例如JDBC。 Java 的并发模型是线程(系统线程),Java 中的所有调用都会阻塞线程,直到调用返回。那么如何将它们封装在actor中呢? Actor 的表现和 goroutine 有什么不同吗?
期待任何专业的答案!谢谢!
编辑:
我搜索了一些文档,我猜答案可能是:
- CPU 绑定任务
scala 中没有提供抢占
- 事件驱动调用
由于 Akka 已集成到 scala 中,所以要么使用 Akka 异步包装库(例如 Akka TCP),要么使用 future?
- cgo 调用
???
我更改了这篇文章的标题。我已经了解actor和goroutine的风格区别,我只关心actor中如何处理不同类型的调用,就像gorotuine一样。
编辑:
对不起,我终于知道我的问题到底是什么了:
我们可以像 goroutine 一样让出/恢复演员吗?
或者演员只是一个应该从头到尾运行的计划计算部分?即不能中断整个消息处理。
而且由于Java中的线程模型,我认为它缺乏对基于协程的阻塞调用的底层支持,对吧?例如socket read,如果阻塞,yield协程,当有新数据读到读时,恢复协程;虽然它对程序员是透明的,但您只需要编写 socket.read()。众所周知,在Java中,整个过程都是基于系统线程的,就像C一样是传统的方式。
【问题讨论】:
-
是的,我读过那些帖子。但是他们没有解释如何处理我上面在actor中提到的调用。