产品战略专家梁宁确认出席AICon北京站,分享AI时代下的商业逻辑与产品需求 了解详情
写点什么

Ruby 中的 Concurrency、Actors 和 Rubinius——MenTaLguY 访谈

  • 2008-02-22
  • 本文字数:3366 字

    阅读完需:约 11 分钟

随着 Ruby 1.9 增加了纤程 Fibers(协同程序),以及最近 Erlang 和 Actors 的流行,一组少为人之的概念进入了 Ruby 的编程世界。为了了解 Ruby 世界中的并发程序,我们采访了 Ruby 社区的老会员 MenTaLguY 。他长期致力于 Ruby 中的并发程序和线程机制,例如 fastthread 库,通过 1.8.x 的 MRI 改进了线程机制。最近他还涉猎了 Rubinius 。另外他还是 JRuby 小组的成员。

InfoQ: 请介绍一下你的 Ruby 版 Actors 库?

MenTaLguY: 实际上,我写了两个 Actors 库(已经发布)。一个是 Omnibus 并发库,另一个是 Rubinius 标准库中的一部分。两者都是 Ruby 实现的 Actors 模型的,也就是由 Erlang 普及的并发模型。并发程序, 从代码并行运行的意义上讲,并不难做到。麻烦出现在当不同的控制线程需要共享同一个资源或者通信路径时。如果你对此不采用一些简单的正规模型来进行结构化,基本上就不可能写出正确的或者最起码有意义的代码,尽管他们表面上看起来能“工作”。

“Actors”就是一个正规模型。一个 actor 由一个信箱和一个线程组成。它很灵活,actor 线程可以等待信箱中出现特定种类的消息,然后“执行”相应的动作,另外也可能再发消息发给别的 actor。通过这种自动而显式的消息交换方式,线程可以由一种相对容易理解的方式来通讯。

InfoQ: 它与 Ruby 的线程体系或者 Ruby 中新的纤程 / 协程有什么关系?

MenTaLguY: 我的 actor 库只是简单地把每个 Ruby 线程都关联一个信箱,这样每个线程都有了一个 actor。但这并不是在 Ruby 中使用 actor 的唯一方式。而纤程只是单线程中的协同调度任务,而且你也可以基于 actor 来实现,就像 Tony Arcieri 在他的 Revactor 库中所做的那样。由于纤程比完全线程更轻量级,而且你无需担心抢占问题,因此他的方法很有优势。然而有时你还是需要用完全线程(有时 Ruby 标准库会迫使你使用它)。

Tony 和我曾进行了多次有益的设计讨论;计划让 actor 的实现尽量有好的兼容性,并提供简单的对象协议,让每个 actor 实现都可以使用这个协议。从外部看, actors 同样是多态的——你最终都会把消息提交给一个信箱。基本上不用关心它是到底一个线程还是一个纤程,或者是什么运行在另一个 Ruby 虚拟机上的东西。原则上,actor-duck 甚至还可以由一些 Erlang 进程来支持 (例如通过 Scott Fleckenstein 的 Erlectricity).

InfoQ: 我看到你最近对 Rubinius 库的一些贡献,例如这个对付Actor 。Actors 是用在Rubinius 中吗?

MenTaLguY: 并不是它的一部分(这也是我把它从内核移到标准库中的原因之一)。我认为对它是需求还不到那个程度。

InfoQ: Actors 或者用它们实现的信箱有没有可能被用于 Evan 最近在 Rubinius 加入的 Multi-VM IPC 的消息传递中?

MenTaLguY: Actors 并没有用于实现 MVM IPC 机制,但我们想在幕后使用 MVM IPC 来允许不同 VM 中的 actors 互相通讯。

InfoQ: 现在 Rubinius 线程体系处于什么样的开发状态?都用到了什么——用户线程、内核线程,还是两者的 m:n 混合?

MenTaLguY: 我们在 VM 中使用了用户线程,但每个 VM 都运行在不同的内核线程中。现在,如果你想使用所有的 CPU,就要为每个 CPU 建立一个或两个 VM。Evan 想要最终在 VM 中使用 m:n 模式,但在 Ruby 中还有许多技术难关需要克服。甚至 Ruby 1.9 依然在原生线程上裹足不前,所以实际上他们还是用户线程。

可能只有基于支持原生线程运行时(比如 XRuby、JRuby、IronRuby)的 Ruby 实现才完全支持原生线程。如果 MVM 可以做得更轻量级或者多 CPU 之间的通讯变得足够复杂(世界正日益变得 NUMA 化),原生线程就不会变得那么重要了。

但是,有一种情况无法摆脱原生线程:使用那些不支持异步操作的设计糟糕的 IO API。在这种情况下,你需要使用多原生线程,而不是使用多核。有时你还不得不选择一个专门的进程来等待阻塞调用来结束这些,你的其它代码也随之结束。

但愿将来我们能少看到这种 API。Tony 的 Revactor 库带来了一线希望:他用 actor 来对付 IO,因此你的代码执行可以被 IO 事件驱动,而不是干等着阻塞调用的到来,或者承受控制的变换而变成了巨大的状态机。现在,Revactor 库还用在 MRI 1.9 上,但我们有望移植它,或者在 Ruby 中实现一个类似的库。

InfoQ: Rubinius 好像有了很丰富的并发概念和工具——线程、actor、多虚拟机+消息传递 IPC 等等。

MenTaLguY: 从历史上看,在这一点上,并发是一个非常重要的东西,我想是受了 Rubinius 的影响。

InfoQ: 我注意到其中的一个工具是通道——它在 Rubinius 中扮演什么角色?(我注意到快速调试器使用通道来通知调试器线程等)

MenTaLguY: 通道是 Rubinius 中的基本通讯方式;其它所有方式都基于它。基本的并发模型差不多就是异步的 pi 演算去掉同步和一些诸如非确定性选择之类的公用扩展(需要仲裁通道操作)。我提倡使用 pi 演算通道是由于它的简单性,换句话说是由于它的高效性和可维护性。

现在,pi 演算已经可以很好地直接用于“局部的”(VM 内的)地方,但还不太好用于实现分布式的地方,因为在 pi 演算中,通道两端都是可活动的。由于写操作是异步的,你可以随心所欲地写。但对通道的读操作是同步的。当一个通道遇到多个读操作时,这些读操作必须集中进行。当这些操作互相距离遥远时,就很不妙。

这就是我对 actor 如何应对大规模情况感兴趣的一个原因。Actor 信箱的异步计算特性与通道有点相像,除了只有(异步的)写操作一端是单独可活动的;读操作一端被紧密绑定在一个特定的本地代理上,且不需要考虑“远距离”协调的问题。

InfoQ: Ruby 1.9 增加了纤程和协程——它们是如何在 Rubinius 中实现的?

MenTaLguY: 我认为纤程在有了 Rubinius Tasks 之后实现起来并不麻烦;纤程和 Tasks 其实很相似。

InfoQ: 你对纤程和协程有什么见解和意见吗?你会使用他们吗——用来做什么呢?

MenTaLguY: 我认为他们可以很好地代替状态机,特别是协程令你更自由地使用库代码。不过,当状态机足够小或者在一些情况下,比如适合用 Ragel 之类地东西来产生它时,状态机仍是更好地选择。

InfoQ: 你现在拥有对 JRuby 的贡献权对吗?你对 JRuby 的兴趣在哪?或者说你致力于它的哪些方面?

MenTaLguY: 是的。我的主要兴趣是并发程序:Ruby 和原生线程的结合提出了一些有意思的挑战。因此我一直在修正并发程序的错误,并确定我们应该为并发程序提供怎样的保证。有可能的话我想最终把 Java 的并发程序的便利性引入 Ruby,希望通过移植的方式来进行(这也是 Omnibus Concurrency 库的一部分任务)。

InfoQ: 你还参与了其他什么项目吗?

MenTaLguY: 除了偶尔对 Shoes 打些补丁外,我从事一些未发布库的工作,其中大部分将会在准备好的时候发行和公布。这里可以讲讲我最近发行的一个库,尽管还没有正式公布:“case”gem 包。 它可以令 Ruby 的 case-match 运算支持数组、结构体和任意谓语的模式匹配。

<blockquote id="b39p">require 'rubygems'<br></br>require 'case'<br></br>Foo = Case::Struct.new :a, :b<br></br>def example(arg)<br></br> case arg<br></br> when Foo[:blarg, Object] # matches any Foo with .a == :blarg<br></br> # ...<br></br> when Foo[10, 20] # matches only a Foo with .a == 10 and .b == 20<br></br> # ...<br></br> when Foo # matches any Foo<br></br> # ...<br></br> when Case::Any[String, Array] # matches either a String or Array<br></br> # ...<br></br> # matches a three-element array with initial elements 1, 2:<br></br> when Case[1, 2, Object]<br></br> # ...<br></br> # matches any Integer > 10:<br></br> when Case::All[Integer, Case.guard { |n| n > 10 }]<br></br> # ...<br></br> end<br></br>end</blockquote>Tony 和我在我们的 actor 库中使用 case-match 运算符(===)来选择特定种类的消息去等待。因此。这个 gem 包在这里很有用。

欲详细了解 MenTaLguY,请访问他的博客 http://moonbase.rydia.net/ 或者关注他所参与的项目。要详细了解 Actors,请阅读最近对Tony Arcieri 的采访,他是Revactor 的开发者。 Revactor 是一个为高性能网络应用开发的应用程序框架。它面向 Ruby 1.9,并使用了诸如纤程的并发特性。关于 Rubinius 的详情,请参见 InfoQ 的 Rubinius 专题内容

查看英文原文: Ruby Concurrency, Actors, and Rubinius - Interview with MenTaLguY

2008-02-22 02:481297
用户头像

发布了 33 篇内容, 共 50812 次阅读, 收获喜欢 0 次。

关注

评论

发布
暂无评论
发现更多内容

Android 设备音视频兼容性适配

网易云信

WebRTC

区块链赋能的Web 3.0时代将是一番怎样的景象?

CECBC

区块链

从字节跳动到火山引擎(一) | Redis 云原生实践

redis 字节跳动 Kubernetes 云原生 火山引擎

000 ES suggest-英文

小林-1025

es7

跨湖跨仓场景下如何实现海量数据分钟级分析

华为云开发者联盟

大数据 数据湖 数据分析 华为云FusionInsight MRS HetuEngine

区块链技术赋能不动产登记,让群众办事更便利

CECBC

区块链

干了八年的阿里面试官,给大家分享我面试时最爱问的Java面试题

Java架构师迁哥

领域驱动设计(DDD)在百度爱番番的实践

百度Geek说

中台 微服务 领域驱动设计DDD

击破行业痛点,区块链赋能智慧物流高速发展

CECBC

区块链

江西组织部干部人事综合管理平台建设,干部管理系统

华为云云原生数据库GaussDB加速创新,企业核心数据上云信赖之选

华为云开发者联盟

数据库 云原生 华为云 GaussDB(for openGauss) 全密态安全

海南新场景!数字人民币在三亚完成首单离岛免税购物

CECBC

海口免税

一周信创舆情观察(4.19~4.25)

统小信uos

阿里云 ARMS 3.0 重磅发布云拨测,Gartner APM 魔力象限产品解读

阿里巴巴中间件

阿里云 Gartner 可观测

uni-app rtc插件集成指南及常见问题--iOS

anyRTC开发者

uni-app ios 音视频 WebRTC RTC

anyRTC 音视频 uni 插件集成步骤

anyRTC开发者

uni-app android 音视频 WebRTC sdk

行业洞察 | 风口上的互联网医疗,如何赢得下半场?

澳鹏Appen

人工智能 大数据 医疗方案 智能医疗 医疗AI

复习一周 成功拿到字节Offer 我也惊呆了

学Java关注我

Java 面试 程序人生 编程语言 计算机

系统服务-技术专题-并发模型粗浅分析探讨

洛神灬殇

并发编程

音频技术及行业的发展

Emotion

音频技术

【Java面试】30个 Java 集合面试必备的问题和答案 ​

Java架构师迁哥

云图说|数据可视化管理,搭载数据安全黑科技!华为数据安全中心,助你保障云上数据安全!

华为云开发者联盟

数据安全 华为云 云图说 DSC 数据安全中心 云上数据

本科学历,杭州工作4年,三个月学习入职阿里,薪资涨幅达到50%

比伯

Java 编程 程序员 架构 计算机

CrossOver for Mac 怎么用?

懒得勤快

编曲混音必备法宝——FL三大效果器简介

奈奈的杂社

Kubernetes入门——Kubernetes实现应用的高可用

百度开发者中心

Kubernetes k8s入门 #技术课程#

高并发系列:架构优化之细说负载均衡

Coder的技术之路

负载均衡 高并发 高并发优化 负载均衡架构

基于 HLS 创建 Golang 视频流服务器

天黑黑

音视频 HLS 声网 Go 语言

5.1特辑|为何显示有票你却抢不到?技术揭秘12306如何保证车票不超卖

华为云开发者联盟

数据库 GaussDB(for Redis) 五一 12306 数据强一致性

站在车顶才能维权?中汽协基于区块链放“大招”!

CECBC

特斯拉

Rust从0到1-集合-Vector

rust 集合 Collections vecotr

Ruby中的Concurrency、Actors和Rubinius——MenTaLguY访谈_Ruby_Werner Schuster_InfoQ精选文章