Ruby | Introduction to Multi-threading

Multi-threading is the most useful property of Ruby which allows concurrent programming of two or more parts of the program for maximizing the utilization of CPU. Each part of a program is called Thread. So, in other words, threads are lightweight processes within a process. An ordinary program contains single thread and all the statements or instructions are executed sequentially. But a multi-threaded program contains more than one thread and within each thread statements or instructions execute sequentially, but the thread itself executes concurrently on the multi-core processor. Multi-threading reduces the memory usage as compared to a single thread by performing multiple tasks. Before Ruby 1.9, threads were switched within the interpreter which are termed as Green Threads. But from Ruby 1.9 onwards, threading is performed by the operating system. The two threads running in the same Ruby application can never be truly concurrent. In Ruby, a multi-threaded program is created with the help of Thread class and a new thread is created by calling a block, i.e Thread.new.

Creating Threads in Ruby

In Ruby, creating a new thread is very easy. There are three blocks (Thread.new, Thread.start, or Thread.fork) by which you can create a thread in a program. Generally, Thread.new is used to create the thread. Once the thread created, the original thread will return from one of these Thread creation blocks and resume the execution with the next statement.



Syntax:

# Original thread is running

# creating thread
Thread.new
{
    # new thread runs here
}

# Outside the block
# Original thread is running

Example:

filter_none

edit
close

play_arrow

link
brightness_4
code

# Ruby program to illustrate 
# creation of threads
  
#!/usr/bin/ruby 
  
# first method
def Geeks1
   a = 0
   while a <= 3
  
       puts "Geeks1: #{a}"
  
      # to pause the execution of the current
      # thread for the specified time
      sleep(1)
  
      # incrementing the value of a
      a = a + 1
   end
  
end
  
# Second method
def Geeks2
   b = 0
  
   while b <= 3
  
       puts "Geeks2: #{b}"
  
      # to pause the execution of the current
      # thread for the specified time
      sleep(0.5)
  
      # incrementing the value of a
      b = b + 1
   end
  
end
  
# creating thread for first method
x = Thread.new{Geeks1()}
  
# creating thread for second method
y= Thread.new{Geeks2()}
  
# using Thread.join method to 
# wait for the first thread 
# to finish
x.join
  
# using Thread.join method to 
# wait for the second thread 
# to finish
y.join
  
  
puts "Process End"

chevron_right


Output:

Geeks1: 0
Geeks2: 0
Geeks2: 1
Geeks1: 1
Geeks2: 2
Geeks2: 3
Geeks1: 2
Geeks1: 3
Process End

Note: Output may be different as resources to threads are allocated by the operating system.


Terminating Threads

When a Ruby program is terminated, all the threads related to that program is also killed. A user can kill the threads using class ::kill.

Syntax:

Thread.kill(thread)

Thread variables and their Scope

As threads are defined by the blocks so they have access to local, global and instance variables which are defined in the scope of the block. Variables present in the block of the thread are the local variables for that thread and they are not accessed by any other thread block. Thread class allows a thread-local variable to be created and accessed by their name. If two or more threads wants to read and write the same variable concurrently then there must be thread synchronization.

Example:

filter_none

edit
close

play_arrow

link
brightness_4
code

# Ruby program to illustrate 
# Thread variables
   
#!/usr/bin/ruby 
  
# Global variable 
$str = "GeeksforGeeks" 
  
# first method
def Geeks1
  
   # only access by Geeks1 Thread
   a = 0
  
   while a <= 3
   
       puts "Geeks1: #{a}"
   
      # to pause the execution of the current
      # thread for the specified time
      sleep(1)
   
      # incrementing the value of a
      a = a + 1
  
  
   end
    
  # accessing str
  puts "Global variable: #$str"
  
end
   
# Second method
def Geeks2
  
   # only access by Geeks2 Thread
   b = 0
   
   while b <= 3
   
       puts "Geeks2: #{b}"
   
      # to pause the execution of the current
      # thread for the specified time
      sleep(0.5)
   
      # incrementing the value of a
      b = b + 1
   end
   
  # accessing str
  puts "Global variable: #$str"
  
end
   
# creating thread for first method
x = Thread.new{Geeks1()}
   
# creating thread for second method
y= Thread.new{Geeks2()}
   
# using Thread.join method to 
# wait for the first thread 
# to finish
x.join
   
# using Thread.join method to 
# wait for the second thread 
# to finish
y.join
   
   
puts "Process End"

chevron_right


Output:

Geeks1: 0
Geeks2: 0
Geeks2: 1
Geeks1: 1
Geeks2: 2
Geeks2: 3
Geeks1: 2
Global variable: GeeksforGeeks
Geeks1: 3
Global variable: GeeksforGeeks
Process End


My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.




Article Tags :

Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.