Nearby lessons
146 of 159Python - Threading Quick Revision
- Revise all threading concepts from the chapter
- Recall thread creation and management methods
- Recall synchronization mechanisms and when to use each
- Recall inter thread communication options
- Prepare for interview and examination questions
Python Threading Complete Summary
This section provides a quick revision of all important concepts covered in Python Multi Threading.
We have learned about:
- Multi Tasking
- Process Based Multi Tasking
- Thread Based Multi Tasking
- Applications of Multi Threading
- Python threading module
- Main Thread
- Creating Threads
- Thread methods
- Thread information
- Daemon Threads
- Synchronization
- Lock
- RLock
- Semaphore
- BoundedSemaphore
- Inter Thread Communication
- Event
- Condition
- Queue
1. What is Multi Tasking?
Multi Tasking means executing several tasks simultaneously.
There are two types of Multi Tasking:
- Process Based Multi Tasking
- Thread Based Multi Tasking
Multi Tasking
│
┌─────────┴─────────┐
│ │
▼ ▼
Process Based Thread Based
Multi Tasking Multi Tasking
Simple Definition:
Executing several tasks simultaneously is called Multi Tasking.
2. Process Based Multi Tasking
In Process Based Multi Tasking, every task runs as a separate process.
It is best suitable at the Operating System level.
Examples:
- Editing a Python program
- Listening to MP3 songs
- Downloading a file
All these tasks execute independently.
Operating System
│
├── Process 1 → Edit Python Program
│
├── Process 2 → Play MP3 Song
│
└── Process 3 → Download File
3. Thread Based Multi Tasking
In Thread Based Multi Tasking, multiple independent parts of the same program execute simultaneously.
Each independent part is called a Thread.
Thread Based Multi Tasking is best suitable at the program level.
One Program
│
┌─────────┼─────────┐
│ │ │
▼ ▼ ▼
Thread-1 Thread-2 Thread-3
Simple Definition:
A Thread is an independent part of the same program.
Process Based vs Thread Based Multi Tasking
| Process Based | Thread Based |
|---|---|
| Each task is a separate process. | Each task is an independent part of the same program. |
| Best suitable at OS level. | Best suitable at program level. |
| Processes execute independently. | Multiple Threads belong to the same program. |
4. Applications of Multi Threading
Important applications of Multi Threading include:
- Multimedia Graphics
- Animations
- Video Games
- Web Servers
- Application Servers
Multi Threading
│
├── Multimedia Graphics
├── Animations
├── Video Games
├── Web Servers
└── Application Servers
5. Python Thread Module
Python provides the built-in module:
threading
to develop multi-threaded applications.
We can import it using:
import threading
or:
from threading import *
6. Main Thread
Every Python program contains one default Thread.
It is called:
MainThread
The Main Thread starts automatically when the Python program starts.
Python Program Starts
│
▼
MainThread
│
▼
Execute Program
7. Ways to Create Threads
Python supports three ways to create Threads:
- Creating a Thread without using any class
- Creating a Thread by extending the
Threadclass - Using a normal class object as Thread target
| Method | Concept |
|---|---|
| Method 1 | Create Thread with a target function |
| Method 2 | Extend Thread and override run() |
| Method 3 | Use a normal class method as the Thread target |
Thread Creation - Quick Example
Thread Creation - Execution Flow
Program Starts
│
▼
MainThread
│
▼
Create Thread Object
│
▼
t.start()
│
▼
Child Thread Starts
│
├──────────► display()
│
▼
Main Thread Continues
The exact execution order can vary because Thread scheduling is not predictable.
8. Important Thread Methods
The important Thread methods covered in this tutorial are:
start()run()join()
| Method | Purpose |
|---|---|
start() |
Starts the Thread |
run() |
Contains the work performed by the Thread |
join() |
Makes one Thread wait until another Thread completes |
join() Method
The join() method makes one Thread wait until another Thread completes its execution.
t.join()
We can also specify a waiting time:
t.join(seconds)
In this case, the calling Thread waits for the specified amount of time or until the target Thread completes.
9. Thread Name Methods
Every Thread has a name.
The tutorial covers the name property.
Every Thread receives a default name, which can be changed.
t.name t.name = "MyThread"
10. Thread Identification Number
Every Thread has a unique identification number.
It can be accessed using:
ident
Example:
t.ident
This provides the identification number associated with the Thread.
11. active_count()
active_count() returns the number of currently active Threads.
active_count()
Conceptually:
Currently Running Threads
MainThread
Thread-1
Thread-2
active_count()
│
▼
3
12. enumerate()
enumerate() returns a list containing all currently active Thread objects.
enumerate()
It can be used when we want information about all active Threads.
13. is_alive()
is_alive() checks whether a Thread is still executing.
t.is_alive()
Conceptually:
Thread Running
│
▼
True
Thread Completed
│
▼
False
Thread Information - Quick Revision
| Method / Property | Purpose |
|---|---|
name |
Get or change Thread name |
ident |
Get Thread identification number |
active_count() |
Count active Threads |
enumerate() |
Return active Thread objects |
is_alive() |
Check whether Thread is executing |
14. Daemon Threads
Daemon Threads run in the background and provide support to Non-Daemon Threads.
Example:
- Garbage Collector
When the last Non-Daemon Thread terminates, the remaining Daemon Threads terminate automatically.
Main Thread
Non-Daemon Threads
│
▼
All Complete
│
▼
Remaining Daemon Threads
Terminate Automatically
15. Synchronization
Synchronization is used to avoid data inconsistency when multiple Threads access shared resources.
The synchronization techniques covered are:
- Lock
- RLock
- Semaphore
Synchronization
│
├── Lock
├── RLock
└── Semaphore
Simple Definition:
Synchronization controls concurrent access to shared resources so that data inconsistency can be avoided.
Why Synchronization?
Without proper synchronization, multiple Threads may access the same shared resource simultaneously.
Thread-1 ─────┐
│
▼
Shared Resource
▲
│
Thread-2 ─────┘
Possible Problem
│
▼
Data Inconsistency
Synchronization controls access to the shared resource.
16. Lock
A Lock allows only one Thread at a time to enter the protected section.
Important methods:
acquire() release()
Basic pattern:
l.acquire() # Critical Section l.release()
Thread-1 │ ▼ Acquire Lock │ ▼ Critical Section │ ▼ Release Lock │ ▼ Next Waiting Thread
17. RLock
RLock means Reentrant Lock.
The same Thread can acquire an RLock multiple times.
This is useful for:
- Recursive functions
- Nested resource access
Same Thread
│
├── acquire()
├── acquire()
├── acquire()
│
▼
Allowed with RLock
The Thread must release the RLock appropriately for its acquisitions.
Lock vs RLock
| Lock | RLock |
|---|---|
| A Thread cannot safely acquire the same Lock again while already holding it. | The owning Thread can acquire the same RLock multiple times. |
| Repeated acquisition by the same Thread can block it. | Supports reentrant acquisition. |
| Suitable for basic synchronization. | Useful for recursive and nested locking. |
18. Semaphore
A Semaphore allows a fixed number of Threads to access a protected section simultaneously.
Example:
s = Semaphore(3)
Here, up to three Threads can acquire the Semaphore at the same time.
Semaphore(3) Thread-1 ──► Allowed Thread-2 ──► Allowed Thread-3 ──► Allowed Thread-4 ──► Wait Thread-5 ──► Wait
Lock vs Semaphore
| Lock | Semaphore |
|---|---|
| Only one Thread can acquire it at a time. | A fixed number of Threads can acquire it at the same time. |
| Used for exclusive access. | Used for limited concurrent access. |
19. BoundedSemaphore
BoundedSemaphore is similar to Semaphore.
The important difference is that it prevents the Semaphore counter from being released beyond its initial bound.
The tutorial demonstrates this with extra release() calls.
s = BoundedSemaphore(2) s.acquire() s.acquire() s.release() s.release() # Extra release s.release()
This results in:
ValueError: Semaphore released too many times
This can help detect programming mistakes involving unmatched release() operations.
20. Inter Thread Communication
Sometimes multiple Threads need to communicate with each other.
This concept is called Inter Thread Communication.
Python mechanisms covered in the tutorial are:
- Event
- Condition
- Queue
Inter Thread Communication
│
┌─────────┼─────────┐
│ │ │
▼ ▼ ▼
Event Condition Queue
Producer-Consumer Concept
A common example of Inter Thread Communication is the Producer–Consumer model.
Producer Thread
│
▼
Produce Item
│
▼
Communicate
│
▼
Consumer Thread
│
▼
Consume Item
The Producer creates new items, while the Consumer waits for and consumes those items.
21. Event
An Event provides a simple mechanism for communication between Threads.
Important methods covered in the tutorial:
set()clear()is_set()wait()
| Method | Purpose |
|---|---|
set() |
Sets the internal flag to True |
clear() |
Sets the internal flag to False |
is_set() |
Checks whether the Event is set |
wait() |
Waits until the Event becomes set |
Event - Quick Flow
Consumer │ ▼ event.wait() │ ▼ Waiting │ │ │ Producer │ ▼ event.set() │ ▼ Consumer Continues
22. Condition
Condition provides a more advanced communication mechanism.
Important methods:
acquire()release()wait()notify()notify_all()
| Method | Purpose |
|---|---|
acquire() |
Acquire the associated Lock |
release() |
Release the associated Lock |
wait() |
Wait for notification |
notify() |
Notify one waiting Thread |
notify_all() |
Notify all waiting Threads |
Condition - Producer Consumer Flow
Consumer │ ▼ acquire() │ ▼ wait() │ ▼ Waiting ▲ │ │ notify() │ Producer │ ▼ acquire() │ ▼ Produce Item │ ▼ notify() │ ▼ release()
The Consumer generally waits, while the Producer performs the update and sends the notification.
23. Queue
Queue provides an easy and powerful mechanism for sharing data between Threads.
The important methods are:
put()get()
Producer │ ▼ q.put(item) │ ▼ Queue │ ▼ q.get() │ ▼ Consumer
Queue automatically handles:
- Locking
- Waiting
- Notification
Queue Behaviour
If a bounded Queue is full, a blocking Producer waits until space becomes available.
If the Queue is empty, a blocking Consumer waits until an item becomes available.
Queue Full
│
▼
Producer Waits
Queue Empty
│
▼
Consumer Waits
This synchronization is handled automatically by Queue.
Event vs Condition vs Queue
| Event | Condition | Queue |
|---|---|---|
| Simple communication mechanism | More advanced communication mechanism | Most enhanced mechanism covered in the tutorial |
| Works using an internal flag | Uses waiting and notification with locking | Designed for synchronized data sharing |
set(), clear(), wait() |
wait(), notify(), etc. |
put(), get() |
| Useful for signaling | Useful when manual control is required | Very convenient for Producer–Consumer communication |
Complete Threading Concept Flow
Python Multi Threading
│
├── Multi Tasking
│ ├── Process Based
│ └── Thread Based
│
├── threading Module
│
├── MainThread
│
├── Thread Creation
│ ├── Target Function
│ ├── Extend Thread
│ └── Normal Class Method
│
├── Thread Operations
│ ├── start()
│ ├── run()
│ └── join()
│
├── Thread Information
│ ├── name
│ ├── ident
│ ├── active_count()
│ ├── enumerate()
│ └── is_alive()
│
├── Daemon Threads
│
├── Synchronization
│ ├── Lock
│ ├── RLock
│ ├── Semaphore
│ └── BoundedSemaphore
│
└── Inter Thread Communication
├── Event
├── Condition
└── Queue
Complete Revision Table
| Topic | Important Points |
|---|---|
| Multi Tasking | Process Based and Thread Based |
| Thread Module | threading |
| Main Thread | MainThread |
| Thread Creation | Three ways |
| Main Methods | start(), run(), join() |
| Thread Information | name, ident, active_count(), enumerate(), is_alive() |
| Daemon Thread | Background support Thread |
| Synchronization | Lock, RLock, Semaphore |
| Lock | One Thread at a time |
| RLock | Same owning Thread can acquire multiple times |
| Semaphore | Fixed number of Threads can access simultaneously |
| BoundedSemaphore | Prevents releases beyond the initial bound |
| Inter Thread Communication | Event, Condition, Queue |
| Event Methods | set(), clear(), is_set(), wait() |
| Condition Methods | acquire(), release(), wait(), notify(), notify_all() |
| Queue Methods | put(), get() |
Summary
- Multi Tasking means executing several tasks simultaneously.
- Multi Tasking can be Process Based or Thread Based.
- A Thread is an independent part of the same program.
- Python provides the
threadingmodule for Multi Threading. - Every Python program starts with a default
MainThread. - Python supports three approaches to creating Threads covered in this tutorial.
start()starts a Thread.run()contains the Thread's job when working with the Thread class.join()can make one Thread wait for another.- Thread information can be obtained using names,
ident,active_count(),enumerate(), and Thread-status methods. - Daemon Threads provide background support to Non-Daemon Threads.
- Synchronization is used to protect shared resources from data inconsistency.
- Lock permits one Thread at a time.
- RLock supports repeated acquisition by the owning Thread.
- Semaphore permits a fixed number of Threads simultaneously.
- BoundedSemaphore can detect excessive releases.
- Event, Condition, and Queue are used for Inter Thread Communication.
- Event provides simple signaling.
- Condition provides controlled waiting and notification.
- Queue simplifies synchronized data sharing between Producer and Consumer Threads.
Important Notes
- The
threadingmodule is used to develop multi-threaded Python applications. - Every Python program contains a Main Thread.
- The execution order of multiple Threads is generally not predictable.
start()should be used to start a Thread.join()is used when one Thread must wait for another Thread.identprovides the Thread identification number.active_count()returns the number of active Threads.enumerate()returns active Thread objects.- Daemon Threads work in the background to support Non-Daemon Threads.
- Synchronization is important when multiple Threads access shared resources.
- Lock provides exclusive access to one Thread at a time.
- RLock is useful when the owning Thread needs to acquire the same lock repeatedly.
- Semaphore allows a fixed number of Threads to enter simultaneously.
- BoundedSemaphore helps identify incorrect extra
release()operations. - Event is the simplest Inter Thread Communication mechanism covered in this tutorial.
- Condition provides more control over waiting and notification.
- Queue provides automatic synchronization for Producer–Consumer data sharing.
- The Producer generally uses
put()with Queue. - The Consumer generally uses
get()with Queue. - Queue automatically handles locking, waiting, and notification.
- Multi tasking is the base of multi threading
- Threads are created via Thread(target=...) and started with start()
- Lock, RLock, and Semaphore provide synchronization
- Event, Condition, and Queue enable inter thread communication