Ruby Threading

Aidanmc
3 min readJun 3, 2020

Ruby threading is actually easier than you think. All you really have to do is encapsulate the piece of code that you want to be processed at the same time using:

Thread.new{}

By calling this function multiple time we can have the program process multiple threads at the same time. Perfect and we are done right.

2.times do |i|    Thread.new {        10000000.times do |t|        t + 1        end        ending = Time.now        elapsed = ending - starting        puts ("#{i} End:" + elapsed.to_s)     }endending = Time.nowelapsed = ending - startingputs ("Main End:" + elapsed.to_s)

Now if we try and put this code into ruby and run everything the run time will be great. But hold up where did the, puts ("#{i} End:" + elapsed.to_s), code go? We are unable to find any mention of time elapsed for each run. This is because when working with threads in Ruby we need to join the thread back with the main program for any of its information to be present. If the main program finishes before the thread then the thread will automatically be terminated with the main program.

To do this we can set the thread equal to a value and then join it back to the main program.

x = Thread.new{}
x.join

This is nice but what happens when we want to work with multiple threads. Do we have to keep creating and joining the new thread each time? Well, know there are ways around this. Such as adding our threads to an array and then joining them each at the end.

Now that we can deal with multiple threads lets test it out.

This is a simple example of threading that will allow us to time our programs. Make sure to require ‘benchmark’ at the top of your file to time your program in two different ways.

All we have to do is delete the “threads << Thread.new{}” portion of code and rerun everything to test this without threading.

Odd when we look at the times side by side they look almost exactly the same.

The problem is that the Global Interpreter Lock mechanism that is built into CRuby is getting in the way.

A Global Interpreter Lock (GIL) is a mechanism used in computer-language interpreters to synchronize the execution of threads so that only one native thread can execute at a time(Wikipedia). This causes Ruby to only work on one thread at a time switch between the two to complete the tasks given.

Though this doesn’t mean there is no point in threading in Ruby it still has multiple implementations. One of the most common uses would be to use threading to set up background information for our program by joining the threads at the end of the program. By doing this our main program will finish running and just before ending it will join everything back together.

Stopping here feels improper there must be a way to speed up the processing of our program? Yes, by using JRuby we would be able to run the above code and have it speed up the process. JRuby is built to run threads with parallelism rather than concurrency like CRuby.

There is one other way in standard Ruby to “thread” and that is by using the fork() method instead of the Thread.new{} method.

By doing this you can have our program act as though it is running multiple applications at the same time. Our computer can only handle so many things running at the same time so if you increase everything too much our terminal will break.

--

--