EZ

Eduzan

Learning Hub

Eduzan
Eduzan / Ruby

Ruby Threading

Computer Science / Ruby tutorial chapter - Published 2025-12-16 - Ruby

Multi-threading in Ruby is a powerful feature that enables the concurrent execution of different parts of a program, optimizing CPU usage. Each part of the program is called a thread, and threads are essentially lightweight processes within a larger process. A single-threaded program executes instructions sequentially, while a multi-threaded program can run multiple threads concurrently, utilizing multiple cores of a processor. This leads to reduced memory usage and improved performance compared to single-threaded programs.

Before Ruby version 1.9, Ruby used green threads, meaning thread scheduling was handled by Ruby’s interpreter. However, from Ruby 1.9 onwards, threading is handled by the operating system, making thread execution more efficient. Despite this improvement, two threads in the same Ruby application still cannot run truly concurrently.

In Ruby, a multi-threaded program can be created using the Thread class. A new thread is usually created by calling a block using Thread.new.

Creating Threads in Ruby

To create a new thread in Ruby, you can use any of three blocks: Thread.newThread.start, or Thread.fork. The most commonly used is Thread.new. Once a thread is created, the main (original) thread resumes execution after the thread creation block, running in parallel with the new thread.

Syntax:

# Main thread runs here

# Creating a new thread
Thread.new {
    # Code to run inside the new thread
}

# Main thread continues executing

Example:

# Ruby program to demonstrate thread creation

def task1
  count = 0
  while count <= 2
    puts "Task 1 - Count: #{count}"
    sleep(1) # Pauses execution for 1 second
    count += 1
  end
end

def task2
  count = 0
  while count <= 2
    puts "Task 2 - Count: #{count}"
    sleep(0.5) # Pauses execution for 0.5 seconds
    count += 1
  end
end

# Creating threads for each task
thread1 = Thread.new { task1() }
thread2 = Thread.new { task2() }

# Ensuring the main program waits for threads to finish
thread1.join
thread2.join

puts "All tasks completed"

Output:

Task 1 - Count: 0
Task 2 - Count: 0
Task 2 - Count: 1
Task 1 - Count: 1
Task 2 - Count: 2
Task 1 - Count: 2
All tasks completed

Note: The exact output may vary depending on how the operating system allocates resources to the threads.

Terminating Threads

When the Ruby program finishes, all associated threads are also terminated. However, you can manually kill a thread using the Thread.kill method.

Syntax:

Thread.kill(thread)

Thread Variables and Scope

Each thread has access to local, global, and instance variables within the scope of the block where it is defined. However, variables defined within a thread block are local to that thread and cannot be accessed by other threads. If multiple threads need to access the same variable concurrently, proper synchronization is required.

Example:

# Ruby program to demonstrate thread variables

# Global variable
$message = "Hello from Ruby!"

def task1
  counter = 0
  while counter <= 2
    puts "Task 1 - Counter: #{counter}"
    sleep(1)
    counter += 1
  end
  puts "Global message: #{$message}"
end

def task2
  counter = 0
  while counter <= 2
    puts "Task 2 - Counter: #{counter}"
    sleep(0.5)
    counter += 1
  end
  puts "Global message: #{$message}"
end

# Creating threads for each task
thread1 = Thread.new { task1() }
thread2 = Thread.new { task2() }

# Waiting for both threads to finish
thread1.join
thread2.join

puts "Program finished"

Output:

Task 1 - Counter: 0
Task 2 - Counter: 0
Task 2 - Counter: 1
Task 1 - Counter: 1
Task 2 - Counter: 2
Task 1 - Counter: 2
Global message: Hello from Ruby!
Global message: Hello from Ruby!
Program finished

In Ruby, threads are utilized to implement concurrent programming. Programs that require multiple threads use the Thread class, which provides a variety of methods to handle thread-based operations.

Public Class Methods

1. abort_on_exception: This method returns the status of the global “abort on exception” setting. By default, its value is false. If set to true, all threads are aborted when an exception is raised in any of them.

Thread.abort_on_exception -> true or false

2. abort_on_exception=: This method sets the new state of the global “abort on exception” flag. When set to true, threads are aborted when an exception arises. The return value is a boolean.

Thread.abort_on_exception= bool -> true or false

Example:

# Ruby program to demonstrate abort_on_exception

Thread.abort_on_exception = true

thread = Thread.new do
  puts "Starting new thread"
  raise "An error occurred in the thread"
end

sleep(0.5)
puts "Execution complete"

Output:

Starting new thread
RuntimeError: An error occurred in the thread

3. critical: Returns the current “thread critical” status. This flag indicates whether Ruby’s thread scheduler is in a critical section.

Thread.critical -> true or false

4. critical=: This method sets the global “thread critical” condition. When set to true, it blocks scheduling of any thread but allows new threads to be created and run. Thread-critical sections are used mainly in threading libraries.

Thread.critical= bool -> true or false

5. current: This method returns the currently running thread.

Thread.current -> thread

6. exit: Terminates the current thread and schedules another thread to run. If the thread is marked to be killed, it will return the thread. If it’s the main thread or the last thread, the program will exit.

Thread.exit

7. fork: Similar to start, this method initiates a new thread.

Thread.fork { block } -> thread

8. kill: This method terminates a specified thread.

Thread.kill(thread)

Example:

# Ruby program to demonstrate the kill method

counter = 0

# Create a new thread
thread = Thread.new { loop { counter += 1 } }

# Sleep for a short time
sleep(0.4)

# Kill the thread
Thread.kill(thread)

# Check if the thread is alive
puts thread.alive?  # Output: false

9. list: This method returns an array of all the thread objects, whether they are runnable or stopped.

Thread.list -> array

Example:

# Ruby program to demonstrate list method

# First thread
Thread.new { sleep(100) }

# Second thread
Thread.new { 1000.times { |i| i*i } }

# Third thread
Thread.new { Thread.stop }

# List all threads
Thread.list.each { |thr| p thr }

Output:

#<Thread:0x00007fc6fa0a8b98 sleep>
#<Thread:0x00007fc6fa0a8cf8 run>
#<Thread:0x00007fc6fa0a8d88 sleep>

10. main: This method returns the main thread of the process. Each run of the program will generate a unique thread ID.

Thread.main -> thread

Example:

# Ruby program to print the main thread's ID

puts Thread.main

Output:

#<Thread:0x00007fcd92834b50>

11. new: Creates and runs a new thread. Any arguments passed are given to the block.

Thread.new([arguments]*) { |arguments| block } -> thread

12. pass: Attempts to pass execution to another thread. The actual switching depends on the operating system.

Thread.pass

13. start: Similar to new. If the Thread class is subclassed, calling start from the subclass will not invoke the subclass’s initialize method.

Thread.start([arguments]*) { |arguments| block } -> thread

14. stop: Stops the current thread, putting it to sleep and allowing another thread to be scheduled. It also resets the critical condition to false.

Thread.stop

Example:

# Ruby program to demonstrate stop and pass methods

thread = Thread.new { print "Start"; Thread.stop; print "End" }

# Pass control to another thread
Thread.pass

print "Main"
thread.run
thread.join

Output:

StartMainEnd
End of lesson.