Ruby Thread

Thread means lightweight sub-process. It is a separate path of execution. In Ruby, different parts of a program can run at the same time by either splitting tasks within a program using multiple threading or splitting tasks between different programs using multiple process.

Threads are the Ruby implementation for a concurrent programming model.


Ruby Multithreading

A normal program has single thread of execution. All the statements in the program are executed sequentially.

A multi thread program has more than one thread of execution in it. It uses less memory space and share same address space. Multithreading is used to perform more than one task at once.

A new thread is created using thread.new call. It is different from the main thread’s execution.


Thread Initialization

To create a new thread Ruby provides three keywords namely, ::new, ::start and ::fork.

To start a new thread, associate a block of code with a call to Thread.new, Thread.start or Thread.fork. Thread will be created. The new thread exits when the block exit.

Syntax:

# Original thread runs  

Thread.new {  

  # New thread is created.  

}  

# Original thread runs

Thread Termination

There are different ways to terminate a thread in Ruby. To exit a given thread, class ::kill is used.

Syntax:

thr = Thread.new { ... }  

Thread.kill(thr)

Ruby Thread Example

#!/usr/bin/ruby   

th = Thread.new do #Here we start a new thread   

  Thread.current['counter']=0   

  5.times do |i| #loop starts and increases i each time   

    Thread.current['counter']=i   

    sleep 1   

  end   

  return nil   

end   

while th['counter'].to_i < 4  do   

=begin   

th is the long running thread   

and we can access the same variable   

from inside the thread here   

=end   

  puts "Counter is #{th['counter']}"   

  sleep 0.5   

end   

puts "Long running process finished!"

Output:

Ruby Thread 1

ADVERTISEMENT

Thread Lifecycle

Once a thread is created, there is no need to start it. It automatically runs when it gets proper CPU resources. The last expression in a block is the value of the thread. If thread has run completely, value method returns the thread value, otherwise value method blocks it and returns when the thread has completed. A number of methods are defined by thread class while running query and manipulate the thread.

By calling a thread’s Thread.join method, you can wait for a particular thread to finish.


Thread Exception Handling

Threads may have some exceptions in them. If exception arises in any thread other than main thread, it depends upon abort_on_exception. By default this option is always false. It means unhandled exception will silently terminate the thread. This can be changed by setting either abort_on_exception = true or $DEBUG to true.

To handle exception, you can use class method ::handle_interrupt. It will handle exceptions asynchronously with threads.


Thread Variables and Scope

Threads are created with blocks. A local variable created within a block is accessible to only thread in which this block is present.

Ruby thread class allows thread-local variables to be created and accessed by name. Thread object is treated like a hash, writing elements using []= and reading them back using [].


Thread Scheduling

Ruby supports scheduling threads by using ::stop and ::pass methods in a program.

The ::stop class method put the current running thread to sleep and schedule the execution of another thread. Once the thread is asleep, instance method wakeup is used to mark thread as eligible for scheduling.

The ::pass class method tries to pass execution to another thread. It depends upon the operating system whether the running thread will switch or not.

Thread priority gives a hint to schedule threads according to their priority. The high priority thread is scheduled first. It also depends upon the operating system. A thread can increase or decrease its own priority as the first action it takes.


Thread Exclusion

Ruby thread exclusion states that, when two threads share the same data and one of the thread modifies that data, then we need to ensure that no thread should see each others data in an inconsistent state. For example, banking server. Where one thread operates money transfer in accounts and other thread is generating monthly report for the customers.


Public Class Methods

MethodDescription
abort_on_exceptionIt returns the status of global “abort on exception” condition. The default is true. When it is set to true, all threads will abort if an exception is raised in any thread.
abort_on_exception=When it is set to true, all threads will abort if an exception is raised. It returns the new state.
currentIt returns the currently executing thread.
exclusive{block}It wraps the block in a single, returning the value of the block.
exitIt terminates the currently running thread and schedules another thread tro run.
kill(thread)It causes the given thread to exit.
fork([args]*){|args| block}It is basically same as ::new method.
handle_interrupt(hash){…}Changes asynchronous interrupt timing.
listReturns an array of thread objects for all threads that are either runnable or stopped.
mainReturns the main thread.
new{…}/ new(*args, &proc)/ new(*args){|args|…}It creates a new thread executing the given block.
passIt gives the thread scheduler a hint to pass execution to another thread. A running thread may or may not switch depending upon the OS.
pending_interrupt?(error = nil)It returns whether or not the asynchronous queue is empty.
start([args]*){|args|block}It is basically same as ::new method.
stopIt stops execution of the current thread, putting it into ‘sleep’ state and schedules execution of another thread.

Public Instance Methods

MethodDescription
thr[sym]It returns the value of a fiber-local variable using either a string or symbol name.
thr[sym]=It creates the value of a fiber-local variable using either a string or symbol name.
abort_on_exceptionIt returns status of “abort on exception” for thr.
abort_on_exception=When set to true, all threads will abort if an exception is raised in this thr.
add_trace_func(proc)Adds proc as a handler for tracing.
alive?It returns true if thr is running or sleeping.
backtraceIt returns current backtrace of target ahead.
backtrace_locations(*args)It returns the execution stack for the target ahead.
exit/kill/terminateIt terminates thr and executes another thread to run.
groupIt returns the ThreadGroup which contains the given thread or returns nil.
inspectIt dumps the name, id and status of thr to a string.
joinThe calling thread will suspend execution and run this thr.
key?(sym)It returns true if the given string exists as a fiber-local variable.
keysIt returns an array of the name of the fiber-local variables.
pending_interrupt?(error=nil)Returns whether or not the asynchronous queue is empty for the target thread.
priorityIt returns the priority of thr.
priority=It sets the priority of thr to integer.
killIt works same as exit.
raiseIt raises an exception from the given thread.
runIt wakes up thr, making it eligible for scheduling.
safe_levelIt returns the safe level in effect for thr.
set_trace_func(proc)It establishes proc on thr as the handler.
statusIt returns the status of thr.
stop?It returns true if thr is sleeping or dead.
terminateIt terminates thr and schedules another thread to run.
thread_variable?(key)It returns true if the given string exists as a thread local variable.
thread_variable_get(key)It returns the value of a thread local variable that has been set.
thread_variable_set(key, value)Set a thread local with key to value.
thread_variableIt returns an array of the thread-local variables.
valueIt waits for thr to complete, using join and returns its value.
wakeupMakes a given thread eligible for scheduling, although it may still remained block on I/O.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *