Sewing programs with the Ruby Thread Class
By: Matthew Masiello
Tags: Programming, Flatiron School, Ruby, Blog

What it looks like to use threads in Ruby

According to the Ruby docs a program that requires multiple “threads” of execution is a good candidate for the Thread class.

Hmm… maybe this would work for having music that plays in the background. The Thread class is Ruby’s way of implementing concurrent programming.

So what is concurrent programming anyway?

A concurrent program is one in which several computations execute in a non-sequential or overlapping manner. Ruby in its natural form is not a concurrent programming language. It is sequential which means each computation must finish before the next one can start.

So imagine without the thread class how would this example execute?:

loop do

fork{exec "afplay", "lib/music/song_one.mp3"}

puts "Playing Song..."

sleep 168 # song length

end puts "Hello World!" ==> "Playing Song..."

(168 seconds later)

"Playing Song..."

(168 seconds later)

"PLaying Song..."

etc...

Well that's not what we want at all…

The program will never reach the next puts. This is due to Ruby kindly executing exactly what is written in a sequential way. So in this case we are stuck in an infinite loop.

Rev up those loops…

Now lets try the same thing using the thread class while we ask the user for some input?:

require 'thread' Thread.new do

loop do

fork{exec "afplay", "lib/music/song_one.mp3"}

sleep 168

end

end puts "Whats up?"

response = gets.chomp while response != "not much" do

puts "Whats up?"

response = gets.chomp

end

So in this case the terminal will execute the afplay command first, then it will sleep for the length of the song, then it will loop.

Because of the thread class Ruby knows to move on to the next method while it concurrently is running the other executions. As long as my answer is never “not much” my program will live, and my music will play on loop for as long as the program is running!

So how do we set up our threads?

First and foremost ruby does not include the thread class as part of its core library, so you must require it before you can initialize a new thread instance.

require 'thread'

With Ruby ready, it’s as easy as initializing a new thread instance:

def tell_me_time

Thread.new do

loop do

puts Time.now

sleep 300 # 5 minutes

end

end

end

Once it has been initialized, you can simply call the method “tell me the time” and every five minutes Ruby will puts the current time.

More Fun With Threads!

So Threads can allow you to run multiple concurrent executions at once. Seems pretty powerful. So what are some other useful tricks we can do with threads…

#join

This method allows a thread to take over as the main thread even if the main program has ceased executing.

require 'thread' puts_world = Thread.new { puts "world!" } puts "hello"

puts_world.join => "hello"

"world!"

So what would happen if we did not use #join?

require 'thread' puts_world = Thread.new { puts "world!" } puts "hello"

puts_world => "hello"

This occurs because without #join the thread will be killed as soon as the main program finishes its final execution.

Another cool feature of the join method is that it can pass executions along a chain:

require 'thread' puts_world = Thread.new { puts "world!" } puts_woohoo = Thread.new { puts "woohoo!"} puts "hello" puts_world.join

puts_woohoo.join => "hello"

"world!"

"woohoo!"

Using #join can make for some powerful dynamic programs.

#stop

This method is useful for stopping/pausing the execution of a thread. It puts the thread to sleep.

But how do we wake it up?

#wakeup

This method is pretty self evident. It is able to wake up a thread that was previously put to sleep.

If other functions are running as a priority, it gets scheduled for wakeup which means it may not run immediately on it being called.

#kill

This method kills the called thread. Ruby will then begin to run another thread or end the process if it is the final thread.

Following the thread back

Ruby is a great language. It is fun to write, looks beautiful, and is nice to beginners. It offers many tricks and useful tools, like the thread class. The best part of learning how to program is discovering all these new tools and figuring out ways to use them in fun and interesting ways.

Sources: