Ruby Multithreading

A typical Ruby program runs sequentually in a single thread, no two things can happen in parallel, everything happens one after the other. Multithreading allows you to execute different parts of the program simultaneously.

What benefit does this provide? Why would a programmer what write multithreaded code?

One reason that you might want to use multithreading is for long running processes. The code below prints a string, executes a block and then prints another string. The final line of this program cannot be executed until the long running process finishes. On my machine this takes 15 seconds.

puts "Start"
start = Time.now

100_000_000.times do
  "some long running process"
end

puts "Time: #{Time.now - start}"
#=> Time: 15.797914

To speed the program up you can execute the long running process in a separate thread. This allows the main thread to execute the last line of the program in a fraction of the time. The long running process can continue running in a separate thread, without halting the main thread.

puts "Start"
start = Time.now

Thread.new {
  100_000_000.times do
    "some long running process"
  end
}

puts "Time: #{Time.now - start}"
#=> Time: 8.9e-05

does Ruby have true multithreading?

In Ruby 1.8 Ruby only had green threads. If your program has green threads it means that the program is still single threaded from the OS perspective. All the scheduling happens inside the single execution thread.

Green threads are designed for machines that do not support native multithreading. The disadvantage of green threads is that they don’t use multiple cores. However, they do help with blocking I/O.

Native threads

From Ruby 1.9 onwards, multithreading is handled with native threads. This means that you can parallelise across multiple cores, in theory. However, Ruby’s Global Interpreter Lock (GIL) enforces that only one thread runs at a time.

Ruby threads are still, therefore, concurrent but not parrallel.

Further reading