来自 Puma 的自述文件:
在 MRI 上,有一个全局 VM 锁 (GVL),可确保一次只有一个线程可以运行 Ruby 代码。但如果您正在进行大量阻塞 IO(例如对 Twitter 等外部 API 的 HTTP 调用),Puma 仍然可以通过允许并行完成 IO 等待来提高 MRI 的吞吐量。
不幸的是,它没有解释提高 MRI 吞吐量的机制。
我知道MRI在调用系统IO时会释放GIL,但这是MIR而不是Puma的改进。
我想知道 Puma 如何并行改进阻塞 IO。
如有任何参考,我们将不胜感激。
Nate Berkopec 在 RubyConf 2022 上进行了关于 Puma 的演讲,他还写了一篇文章解释了多线程,有助于解释这个原因。
简单来说,当有1个阻塞IO时,GVL就会被释放。因此,其他线程可以获取 GVL 并可以处理其他请求。
至于Puma中的
reactor
,它只是为了缓冲请求,只有完成的请求才会发送到线程。在后面,reactor
使用nio4r
。