I’m trying to wrap my head around multi threading from MRI vs JRuby point of view.
I’ve done simple sinatra app:
require 'sinatra'
get '/long' do
sleep(10)
"Long operation finished"
end
get '/other' do
"Time now is #{Time.now}"
end
Running this on ruby 1.9.3 via ruby app.rb I was expecting that when /long was invoked I wouldn’t be able to complete any other request. But it turns out I can call /other in different browser even when /long is waiting for complete.
And I’m stuck here. I thought this should be true for JRuby (when app run e.g. on Trinidad) but not for MRI. I supposed I had to spawn several instances to have it working that way.
Can someone please explain me where I’m wrong? Why I still can get response from other requests even if the long running one blocks?
There is a Global Interpreter Lock in MRI that prevents two threads running together. In your example, your long thread is sleeping (doing nothing) thus MRI can suspend it and run the other thread. IF both threads where taking 100% of cpu time, then you would expect one of the threads to wait for another. If you had JRuby, then you would have each thread taking 100% of CPU time from each core (assuming you have multicore processor), thus your threads wouldnt slow down.
Following article should answer your question in depth: http://ablogaboutcode.com/2012/02/06/the-ruby-global-interpreter-lock/