Like running multiple independent programs simultaneously, running multiple threads simultaneously also has similar features with some added benefits, which are as follows :
- Multiple threads share the same data space along with the main thread within a process. Hence, they can easily share information or can communicate with each other unlike if they were processes.
- Also known as light weight processes, they require less memory overhead and hence are cheaper than processes.
Multi threading is defined as the ability to execute multiple threads simultaneously or concurrently. Hence more than one thread can exists in a single process where:
- The register set and local variables of each threads are stored in the stack.
- The global variables (stored in the heap) and the program codes are shared among all the threads.
Methods for Joining Threads
On invoking the join() method, the calling thread gets blocked until the thread object (on which the thread is called) gets terminated. The thread objects can terminate under any one of the following conditions:
- Either normally.
- Through an ill-handled exception.
- Till the optional timeout occurs.
Hence the join() method indicates wait till the thread terminates. We can also specify a timeout value to the join() method. In such a situation the calling thread may ask the thread to stop by sending a signal through an event object. The join() method can be called multiple times.
Syntax:
object_name.join() OR object_name.join(timeout) where timeout argument is the timeout value.
Example:
Python3
from threading import Thread from threading import Event import time class Connection(Thread): StopEvent = 0 def __init__( self ,args): Thread.__init__( self ) self .StopEvent = args # The run method is overridden to define # the thread body def run( self ): for i in range ( 1 , 10 ): if ( self .StopEvent.wait( 0 )): print ( "Asked to stop" ) break ; print ( "The Child Thread sleep count is %d" % (i)) time.sleep( 3 ) print ( "A Child Thread is exiting" ) Stop = Event() Connection = Connection(Stop) Connection.start() print ( "Main thread is starting to wait for 5 seconds" ) Connection.join( 5 ) print ("Main thread says : I cant't wait for more than 5 \ seconds for the child thread;\n Will ask child thread to stop") # ask(signal) the child thread to stop Stop. set () # wait for the child thread to stop Connection.join() print ("Main thread says : Now I do something else to compensate\ the child thread task and exit") print ( "Main thread is exiting" ) |
Output:
The Child Thread sleep count is 1
Main thread is starting to wait for 5 seconds
The Child Thread sleep count is 2
Main thread says : I cant’t wait for more than 5 seconds for the child thread;
Will ask child thread to stop
Asked to stop
A Child Thread is exiting
Main thread says : Now I do something else to compensate the child thread task and exit
Main thread is exiting
Points to remember while joining threads using join() in Python:
- A run time error occurs when join() method is invoked on the same thread as calling join() on the same thread results in a deadlock condition.
- If the join() method is called on a thread which is yet to be started , then a run time error is raised.
- If the join() has the timeout argument then it should be a floating point number representing the time for the operation of thread in seconds.
- If the join() method has no argument, the until the thread terminates the operation is blocked.
- As the value returned by join() is always None, we should always use isAlive() immediately after join() to check whether the thread is still alive or not.