Ruby 3 Guilds并发模型(译)

文本为翻译Olivier Lacan在其博客上发布的文章,并对内容上做了适当的调整。

英文原文地址:http://olivierlacan.com/posts/concurrency-in-ruby-3-with-guilds/

在Ruby Kaigi 2016 大会上,Ruby VM和GC的作者 Koichi Sasada 为Ruby 3 提出了一个新的并发模型。

我们都知道Ruby 提供了线程去实现并发,但是MRI并不能让Ruby的代码并行的运行。Koichi 致力于解决Ruby并行中,遇到的各种挑战,包括可变对象,竞态条件和线程间同步,最终他提出了一个新的并行并发机制,称为 Guilds。

并发的目标

如果你对并发和并行不太了解,可以先阅读一下这篇文章:并发与并行的区别

为Ruby3 提出 Guilds的基本前提是,保证与Ruby2兼容的情况下实现并行,考虑到GIL限制了并发,所以要尝试通过实现,快速对象共享和提供特殊的对象去共享可变对象。

实现并发在目前的Ruby版本中是一件很困难的事情,这因为程序员需要手动的管理线程,确保不会出现竞态条件。通用的做法是在线程中引入『锁』,像Ruby就提供了线程互斥锁,但它或多或少违反了并行的初衷,『锁』容易使程序变慢,而且不当使用的话,很可能使得并发程序比相同的同步程序还要慢。

Guilds工作原理

Koichi的允许下,我为了让它更好理解,就对他的提案做了适当的缩减。

Guild是基于现有的 线程(thread)和纤程(fiber)实现的。它至少由一个线程组成,并且该线程至少由一个纤程组成。不同Guild中的线程可以并行运行,而相同Guild中的线程不能。一个Guild不能对其他Guild中的对象进行读写。

同一个Guild中的不同线程不能并发运行,这是因为Guild存在一个叫 GGL(Giant Guild Lock)的锁,它是用来确保线程是先后运行的,而不同Gulid的线程是可以并发运行的。

你也可以认为 Ruby 2.x 的程序,就相等于是存在一个Guild的程序。

Guilds间通信

不同Guild间不可以相互读写可变对象,这保证了Guild并发运行时,不会因为并发读写而引发问题。

不可相互读写

不过,Guild可以通过Guild::Channel 提供的接口,将对象复制或移动到其他的Guild中。

Guild::Channeltransfer(object)可以将一个对象深度拷贝到目标Guild中。

同样也可以使用,Guild::Channel中的transfer_membership(object) 将一个对象完全移动到其他的Guild中。

一旦对象被移动到新的Guild后,如果原来持有该对象的Guild,再对它进行访问,将会抛出异常。

这里我们就知道了,Guild是不能在没有复制或移动的情况下共享可变对象的,还有一点非常重要,那就是不可变对象(immutable objects)在『深度冻结』(意思是被该对象引用的对象也是冻结不可变的)的情况下是可以直接在多个Guild间共享的。

下面这个例子,展示可变和不可变对象的区别:

# 像整数,这样的数值类型,默认就是不可变的,而哈希不是。
mutable = [1, { "key" => "value" }, 3].freeze
# 而如果 数组实例及其引用的,字符串和哈希的实例都进行冻结,
# 就会得到一个"深度冻结" 的不可变对象。
immutable = [
  "bar".freeze,
  { "key" => "value".freeze }.freeze
].freeze

使用方法

在Koichi Sasada的研究中,他给出了几个关于如何使用Guilds的例子,我在这里,将其中最小的,关于使用Guild并行计算『斐波那契』的例子进行了简化进行展示。

def fibonacci(n)
  return n if n <= 1
  fibonacci( n - 1 ) + fibonacci( n - 2 )
end

guild_fibonacci = Guild.new(script: %q{
  channel = Guild.default_channel

  while(n, return_channel = channel.receive)
    return_channel.transfer( fibonacci(n) )
  end
})

channel = Guild::Channel.new 
guild_fibonacci.transfer([3, channel])

puts channel.receive

Guild对比线程的优势

在线程中,我们很难判别出,哪些可变对象已经被共享了。而Guilds禁止可变对象的共享,转而提供简单的方式去共享不可变对象,而且Koichi计划提供,通过使用『特殊数据结构』来共享可变对象,『特殊数据结构』会自动隔离有风险的可变代码。

当然,使用Guilds相较于线程来说,有些繁琐,这也是需要有取舍的。

性能

我的理解是,目前Guilds的"C"实现仅有400行代码,虽然该实现现阶段还不能用,但Koichi展示了,运行多个Guilds相比于运行单个Guilds在斐波那契例子上的性能优势。

在双核的Linux虚拟机上运行Window 7,Koichi 观察到以下结果:

这也许不能代表,现实场景中大部分Ruby应用会得到性能上的提升,但我还是等不及想知道,Guilds在RubyBench上的测试结果。

总结

Guilds是一种面向Ruby的,简单易用并且安全的并发方式,非常希望Koichi Sasada和Ruby核心团队能在之后,分享更多关于Guilds的资料。

我对Guilds中移动和复制对象的方法的命名,有一些小看法,因为Guild::Channel. transfer(object)看上去更像是表示交换的意思,而结果仅仅是对象的深度拷贝,我相信transfer_copy(object)或是更简单的 copy(object) 更加适合。还有transfer_membership(object) 移动对象的方法,可以简化命名为channel.transfer(object) 。当然了这些方法的命名也不会是一成不变的。

我非常期望,Ruby核心团队能够将这个新功能,作为实验性质的可选功能发布出去,这样Ruby社区就能参与进去帮助改进和测试。还可以让我们在2020年的Ruby3版本之前,就使用上这个新特性。Guilds将会对Ruby在并发友好性上,做出了积极的影响。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,123评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,031评论 2 384
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,723评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,357评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,412评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,760评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,904评论 3 405
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,672评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,118评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,456评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,599评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,264评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,857评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,731评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,956评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,286评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,465评论 2 348

推荐阅读更多精彩内容