- Aliases
- and operator
- Booleans
- Classes
- Code blocks
- Comments
- Conditional statements
- Console
- Data structures
- datetime module
- Decorator
- Dictionaries
- Docstrings
- enum
- enumerate() function
- Equality operator
- Exception handling
- False
- File handling
- Floats
- For loops
- Formatted strings
- Functions
- Generator
- Greater than operator
- Greater than or equal to operator
- If statement
- in operator
- Indices
- Inequality operator
- Integers
- Iterator
- Lambda function
- Less than operator
- Less than or equal to operator
- List append() method
- List comprehension
- List insert() method
- List pop() method
- List sort() method
- Lists
- Logging
- map() function
- Match statement
- Math module
- Modules
- Multiprocessing
- Multithreading
- None
- not operator
- OOP
- or operator
- Parameters
- print() function
- Random module
- range() function
- Recursion
- Regular expressions
- requests Library
- return statement
- round() function
- Sets
- SQLite
- String join() method
- String replace() method
- String split() method
- Strings
- time.sleep() function
- True
- try...except statement
- Tuples
- Variables
- While loops
- Zip function
PYTHON
Python Multithreading: Syntax, Usage, and Examples
Python multithreading allows you to run multiple threads in parallel within a single process. This is especially useful for I/O-bound tasks like handling multiple web requests, reading files, or making API calls. Python’s threading
module makes it easy to create and manage threads for concurrent execution. However, because of Python’s Global Interpreter Lock (GIL), multithreading doesn’t improve performance for CPU-intensive tasks.
How to Use Python Multithreading
Python provides the threading
module for working with threads. To create and start a new thread, you define a function and pass it as the target
to a Thread
object.
Creating and Running Threads
import threading
def print_numbers():
for i in range(1, 6):
print(i)
# Creating a thread
thread = threading.Thread(target=print_numbers)
# Starting the thread
thread.start()
# Waiting for the thread to finish
thread.join()
threading.Thread(target=function_name)
: Creates a thread that runs the specified function..start()
: Begins execution of the thread..join()
: Blocks the main thread until the created thread finishes execution.
When to Use Multithreading in Python
Multithreading is useful when you want to perform multiple tasks at the same time, especially when those tasks involve waiting. Here are three common scenarios where Python multithreading shines:
1. Handling Multiple User Requests in Web Applications
If you’re building a web application, you might need to process multiple user requests simultaneously. Multithreading ensures that one slow request doesn’t block others.
import threading
def handle_request(user_id):
print(f"Processing request for user {user_id}")
# Creating multiple threads
threads = [threading.Thread(target=handle_request, args=(i,)) for i in range(1, 4)]
for thread in threads:
thread.start()
for thread in threads:
thread.join()
2. Downloading Multiple Files Simultaneously
You can download multiple files at once instead of waiting for each to finish before starting the next.
import threading
import time
def download_file(file_name):
print(f"Downloading {file_name}...")
time.sleep(2) # Simulating download time
print(f"{file_name} downloaded.")
files = ["file1.txt", "file2.txt", "file3.txt"]
threads = [threading.Thread(target=download_file, args=(file,)) for file in files]
for thread in threads:
thread.start()
for thread in threads:
thread.join()
3. Keeping a GUI Responsive While Running Background Tasks
In GUI applications, long-running tasks like data processing can make the interface unresponsive. You can use multithreading to keep the UI active while processing data in the background.
import threading
import time
import tkinter as tk
def load_data():
time.sleep(3) # Simulating a slow operation
label.config(text="Data Loaded!")
root = tk.Tk()
root.geometry("200x100")
label = tk.Label(root, text="Loading...")
label.pack()
# Running the task in a separate thread
thread = threading.Thread(target=load_data)
thread.start()
root.mainloop()
Examples of Python Multithreading
Example 1: Running Multiple Tasks Concurrently
import threading
def task(name):
for _ in range(3):
print(f"Task {name} is running")
threads = [threading.Thread(target=task, args=(i,)) for i in range(1, 4)]
for thread in threads:
thread.start()
for thread in threads:
thread.join()
Example 2: Preventing Race Conditions with Locks
When multiple threads access the same variable, they can interfere with each other. A lock prevents this problem.
import threading
counter = 0
lock = threading.Lock()
def increment():
global counter
for _ in range(100000):
with lock: # Ensuring only one thread modifies the counter at a time
counter += 1
threads = [threading.Thread(target=increment) for _ in range(2)]
for thread in threads:
thread.start()
for thread in threads:
thread.join()
print(f"Final counter value: {counter}")
Example 3: Using a Thread Pool for Efficient Task Execution
If you need to run many small tasks, a thread pool can manage threads more efficiently.
import concurrent.futures
def square_number(n):
return n * n
numbers = [1, 2, 3, 4, 5]
with concurrent.futures.ThreadPoolExecutor() as executor:
results = executor.map(square_number, numbers)
print(list(results)) # Output: [1, 4, 9, 16, 25]
ThreadPoolExecutor
automatically manages a pool of worker threads, reducing the overhead of creating and destroying threads.
Learn More About Python Multithreading
Python Multithreading vs. Multiprocessing
Python multithreading is great for I/O-bound tasks, such as network requests, database queries, and file I/O. However, because of the Global Interpreter Lock (GIL), only one thread runs Python code at a time, meaning multithreading won’t speed up CPU-intensive tasks like image processing or machine learning computations.
If you need to maximize CPU usage, use multiprocessing instead.
Using the Python Multithreading Pool
A thread pool efficiently handles multiple threads when you have many short tasks.
import concurrent.futures
def process_data(item):
return item * 2
data = [10, 20, 30, 40]
with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor:
results = executor.map(process_data, data)
print(list(results)) # Output: [20, 40, 60, 80]
max_workers=2
: Limits the number of threads running at once.
Python Multithreading Libraries
Python provides several libraries for working with multithreading:
threading
– The built-in module for managing threads.concurrent.futures
– Simplifies working with multiple threads usingThreadPoolExecutor
.queue
– Provides thread-safe data structures likeQueue
, making it easier to share data between threads.
When to Avoid Multithreading in Python
Multithreading is not helpful for CPU-intensive tasks because of the GIL. For example, if you need to:
- Perform mathematical calculations on large datasets.
- Process images, videos, or audio files.
- Train machine learning models.
In these cases, use the multiprocessing
module instead.
Python multithreading is a powerful tool for improving performance in I/O-bound applications. You can use it to handle multiple user requests, download files in parallel, and keep GUI applications responsive. However, if your goal is to speed up CPU-heavy computations, multithreading won’t help—multiprocessing is the better choice.
Sign up or download Mimo from the App Store or Google Play to enhance your programming skills and prepare for a career in tech.