threadingModule In Python
As we have seen in the previous tutorial,
threading module is used for creating, controlling and managing threads in python. In this tutorial, we will discuss about various functions and object types defined by the
This module provides the following functions for managing threads:
Here is the code snippet from last tutorial, we will be using this to see the various functions provided by the
threading module in action.
This function returns the number of
Thread objects currently alive.
import time import threading def thread1(i): time.sleep(3) #print('No. printed by Thread 1: %d' %i) def thread2(i): time.sleep(3) #print('No. printed by Thread 2: %d' %i) if __name__ == '__main__': t1 = threading.Thread(target=thread1, args=(10,)) t2 = threading.Thread(target=thread2, args=(12,)) t1.start() t2.start() print("No. of active threads: " + threading.active_count()) t1.join() t2.join()
No. of active threads: 3
Try running the this code in the terminal above. You will see the number of thread count to be 3, because we have created 2 threads and there in the main thread in which the complete execution is taking place.
This function will return the current Thread object, corresponding to the caller's thread of control(which is in the control of caller currently). If the caller's thread of control was not created through the threading module(for example the main thread), then a dummy thread object with limited functionality is returned.
import time import threading def thread1(i): time.sleep(3) #print('No. printed by Thread 1: %d' %i) def thread2(i): time.sleep(3) #print('No. printed by Thread 2: %d' %i) if __name__ == '__main__': t1 = threading.Thread(target=thread1, args=(10,)) t2 = threading.Thread(target=thread2, args=(12,)) t1.start() t2.start() print("Current thread is: " + threading.current_thread()) t1.join() t2.join()
Current thread is: <_MainThread(MainThread, started 16152)>
This function returns the thread identifier of the current thread. This is a nonzero integer value. If we started the thread, then this method will return its identifier, otherwise, it will return None.
We can use this method to index a dictionary of thread-specific data. Thread identifiers may be recycled when a thread exits(stops) and another thread is created.
This method returns a list of all
Thread objects currently alive. The list includes daemonic threads(when the program quits, all the daemon threads associated with it are killed automatically), dummy thread objects created by the current thread, and the main thread.
Terminated threads and threads that have not yet been started are not present in this list.
[<_MainThread(MainThread, started 139890175817472)>, <Thread(Thread-1, started 139890151225088)>, <Thread(Thread-2, started 139890142832384)>]
This method returns the main
Thread object. In normal conditions, the main thread is the thread from which the python interpreter was started.
<_MainThread(MainThread, started 139890175817472)>
This method is used to set a trace function/hook for all the threads started using the
threadingmodule. The trace funtion is passed to
sys.settrace() method for each thread, which is attache to the thread before the
run() method is called.
The callback function which we want to act as the trace function will receive three arguments,
frame (the stack frame from the code being run),
event (a string naming the type of notification), and
arg (an event-specific value)
def hello(frame, event, arg): print("Hello, I am a trace hook.") threading.settrace(hello)
Try updating the code in the terminal at the top. Put the
hello function outside the main method and the statement
threading.settrace(hello) just above the statement where we call the
start method for the threads.
This method is used to set a profile function for all threads started from the threading module. Just like the trace funtion, profile function is also passed to
sys.setprofile() method for each thread, which is attache to the thread before the
run() method is called.
This method returns the thread stack size utilised when creating new threads. The
size argument is optional and can be used to set the stack size to be used for creating subsequent threads, and must be 0 or a positive integer (D=default value is 0).
If changing the thread stack size is unsupported, a RuntimeError is raised.
If the specified stack size is invalid, a ValueError is raised.
Currently 32 KiB is the minimum stack size which is supported to provide enough stack space for the interpreter.
Apart from the above specified functions, the
threading module also defines a constant. If you specify a timeout value which is greater than the value of the
TIMEOUT_MAX constant, you will get an
Apart from the functions specified above, the
threading module also provides many classes whose objects are very useful in creating and managing threads.
Following are some of the Object types:
|Thread||Object that represents a single thread of execution.|
|Lock||Primitive lock object.|
|RLock||RLock or Re-entrant lock object provides ability for a single thread to (re)acquire an already-held lock (recursive locking).|
|Condition||Condition variable object causes one thread to wait until certain "condition" has been satisfied by another thread (such as change in state or some data value)|
|Event||Its a more general version of condition variables, whereby a number of threads can be made to wait for some event to occur and all the threads waiting will only awaken when the event happens.|
|Semaphore||Provides a "counter" of finite resources shared between threads block when none are available.|
|BoundedSemaphore||Similar to a Semaphore but ensures that it never exceeds its initial value.|
|Timer||Similar to Thread, except that it waits for a specified period of time before running.|
|Barrier||Creates a "barrier" at which a specified number of threads must all arrive before they're all allowed to continue.|
The above table gives a brief introduction of various object types in python threading module. We will discuss about all these objects in details in the next few tutorials.