首页 > 解决方案 > 为什么一个 Ruby 程序/进程会产生多个线程?

问题描述

正如标题所说,为什么一个 Ruby 程序或进程会产生多个线程?

例如,如果我运行这样一个简单的程序:

ruby -e 'while true; end'

然后尝试通过运行来计算该程序正在使用的线程数:

ps -o nlwp `echo $(ps aux | pgrep ruby)`

我得到输出:

NLWP

2

这意味着该进程正在使用两个线程。

我在 Linux 上使用 CRuby/YARV 2.5.3。我也用 2.3.8 试过这个,得到了同样的结果。

编辑

使用 Ruby 2.6.0,它似乎只运行一个线程。但是,当我使用该选项启用 JIT 时--jit,它会产生两个线程。

标签: rubyvirtual-machineinterpreter

解决方案


你没有说你使用的是哪个 Ruby 实现,所以我们只能猜测:

  • 一些 Ruby 实现为 I/O 使用单独的线程。
  • 一些 Ruby 实现有一个并发的垃圾收集器,即在一个单独的线程中与 mutator 一起运行的垃圾收集器。
  • 一些 Ruby 实现有一个并行垃圾收集器,即使用多个线程的垃圾收集器。
  • 一些 Ruby 实现具有并发并行垃圾收集器,即垃圾收集器在多个单独的线程中与 mutator 一起运行。
  • 一些 Ruby 实现有一个并发的 JIT 编译器,即在一个单独的线程中与解释器一起运行的 JIT 编译器。
  • 一些Ruby 实现具有并行JIT 编译器,即使用多个线程的JIT 编译器。
  • 一些 Ruby 实现具有并发并行 JIT 编译器,即在多个单独线程中与解释器一起运行的 JIT 编译器。
  • 一些 Ruby 实现使用多个消息传递 VM 实现并发,即它们在单独的线程中每个 CPU 内核运行一个 VM 实例,并通过在这些 VM 之间传递它们来实现 Ruby 线程、纤程等。
  • 一些 Ruby 实现使用单独的线程实现跟踪和统计。
  • 一些 Ruby 实现本身可能运行在另一个运行时之上,该运行时可能会执行上述任何一项操作。

而且可能还有很多其他原因。

例如,YARV 2.6 将在没有 JIT 的情况下使用 2 个线程(引擎和 I/O),在使用 JIT 运行时使用三个(加上 JIT)。


推荐阅读