Ruby GIL 下的多线程是不是要比普通的多进程模式性能要差?

yakczh · December 13, 2014 · Last by darkbaby123 replied at February 06, 2015 · 3735 hits

rt

这要看怎么写程序,如果都不处理,又触到 GIL 的情况,肯定比多进程慢。但是你既然知道 GIL 的存在,可以想办法尽可能降低它的影响的。

  1. Ruby MRI 为了线程安全,用了 GIL 只支持单核。任何时刻只有一个线程在运行:当一个 Thread 阻塞时(比如 IO, sleep 等),就会切换到另个一线程。 所以就算用了 celluloid, puma 自动创建多线程的,MRI 下每个进程还是单核。
  2. 而 Rubinius,JRuby 则没有 GIL,支持多核(每个线程分配一个 cpu)。
  3. 如果 MRI 下要用多核,就要用 sidekiq 之类的跑多个 worker 进程。
  4. 单核不一定比多核慢,很多时候瓶颈不在 CPU,而 MRI 多线程可以保证 IO 并发,所以性能可能是一样的。
  5. 多进程消耗内存,而且进程间难以通信 (只能通过 IO 之类的)。多线程,直接共享变量(内存)。

而 Rubinius,JRuby 则没有 GIL,支持多核(每个线程分配一个 cpu)。

支持多核不一定是每个 thread 一个 CPU 吧。。。还是我对 Rubinius 理解有误?

建议看看 这篇文章 ,作者做了两个例子讲解多进程和多线程的区别。注意例子里面用 fib 代替 sleep 让 CPU 持续工作。

简单地说,Ruby MRI 因为有 GIL 的限制,导致运行 CPU 密集型任务时没有办法发挥 thread 的优势。但如果是 IO 密集型任务或者调用外部服务的任务,GIL 对 thread 的影响就没那么大。process 不会受 GIL 的影响,但更耗内存。

You need to Sign in before reply, if you don't have an account, please Sign up first.