多线程的Ruby程序只使用100%的CPU

4
我正在使用ruby-head和Debian wheezy x64。当我运行一个多线程的ruby脚本时,htop显示它在视觉上使用了多个核心,并且在进程列表中它正在使用100%的CPU,但它只使用了一个核心的100%容量。我认为可能有多个核心正在以100%的速度运行,这个数字似乎太方便了,不会被程序逻辑或其他硬件方面限制。如果操作系统限制了我使用的可用指令数量,那么我该如何阻止这种情况发生?
编辑更多信息:
我的意思是在视觉上使用多个内核,例如:47%内核1,29%内核2和24%内核3。这些百分比不断地上下变化,转移到不同的一组内核上,但总体上始终相加为100%-102%。使用了超过3(/ 8总共)个内核,但除了最负担的三个内核之外的任何内核都只利用2%或更少的容量。我想我还应该提到这是一个linode VPS。
编辑:
看起来我误读了2.0将具有真正的并行线程的承诺,而不是实际的发布信息。是时候转向Jruby了...
2个回答

10

你没有提及你正在使用哪个Ruby实现。并非所有的Ruby实现都能将Ruby线程调度到多个CPU上。

具体而言:

  • MRI将Ruby线程实现为解释器内部的绿色线程,并由其自己进行调度;它不能同时调度多个线程,也不能将它们调度到多个CPU上
  • YARV将Ruby线程实现为本机操作系统线程(POSIX线程或Windows线程),并让操作系统进行调度,但它会在它们周围放置一个巨大的VM锁(GVL),以便任何给定时间只有一个Ruby线程可以运行
  • Rubinius将Ruby线程实现为本机操作系统线程(POSIX线程或Windows线程),并让操作系统进行调度,但它会在它们周围放置一个全局解释器锁(GIL),以便任何给定时间只有一个Ruby线程可以运行;Rubinius 2.0将会有细粒度锁,以便多个Ruby线程可以在任何给定时间运行
  • JRuby将Ruby线程实现为JVM线程,并使用细粒度锁,以便多个线程可以运行;然而,这些线程是否被调度到多个CPU上取决于使用的JVM,一些允许此操作,一些则不允许
  • IronRuby将Ruby线程实现为CLI线程,并使用细粒度锁,以便多个线程可以运行;然而,这些线程是否被调度到多个CPU上取决于使用的VES,一些允许此操作,一些则不允许
  • MacRuby将Ruby线程实现为本机操作系统线程,并使用细粒度锁,以便多个线程可以同时在多个CPU上运行

我不了解Topaz、Cardinal、MagLev、MRuby和所有其他实现。


4

MRI在其解释器中将Ruby线程实现为Green Threads。不幸的是,它不允许这些线程并行调度,它们只能一次运行一个线程。

详见类似问题这里


我以为 Ruby 2.0 已经解决了这个问题。另外,我不确定你的回答是否有意义,因为我明显看到操作系统正在显示多个核心被利用。 - gtech
不,Ruby中的全局解释器锁对于实现真正的多线程是很困难的工作。 - rudolph9
1
啊,抱歉。看起来我只是在阅读该功能的承诺。是时候转向Jruby了。 - gtech
@rudolph9提供的链接到全局解释器锁由于格式错误而出现404错误。这个评论包含了一个修复后的链接。 - Excalibur
@Excalibur 谢谢你让我知道,我会更新我的帖子。 - rudolph9

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接