ruby - 为什么一个 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
,它会产生两个线程。
解决方案
你没有说你使用的是哪个 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)。
推荐阅读
- flutter - Flutter/Dart - 抛出异常时重定向屏幕的按钮?
- python - 如何永远运行 2 个异步函数?
- r - 使用 unz() 将 SAS 数据集读入 R
- c# - 如何在 2D 统一中创建自己的动画?我的意思是,例如,颜色、位置等的变化?
- reactjs - 如何在 Typescript 中将 Promise 合并为一个 Promise
- python - Django:如何为这个 Django 查询集进行自定义排序?
- python - pyglet 中的命名形状
- python - opencv 显示带有边界框和标签的渲染图像
- ruby-on-rails - Rails 关联在哪里 - 为什么不检查类?
- html - 使用 .each() 可调整大小的 jquery ui 仅适用于第一个孩子