Understanding Threading in Python
Threading allows a program to run multiple threads (smaller units of a process) simultaneously.
It’s a powerful technique to improve the efficiency of your application when dealing with I/O-bound operations
or concurrent tasks. Python provides the threading
module, making thread creation and management easy.
This guide introduces the basics of threading and explores useful APIs with practical examples.
Basic Thread Creation
import threading
def print_numbers():
for i in range(5):
print(f"Number: {i}")
# Creating and starting a thread
thread = threading.Thread(target=print_numbers)
thread.start()
# Ensure the thread completes execution
thread.join()
Useful Threading APIs
1. threading.current_thread()
Retrieves the current thread object.
import threading
def display_thread_name():
print(f"Current thread: {threading.current_thread().name}")
thread = threading.Thread(target=display_thread_name, name="MyThread")
thread.start()
thread.join()
2. threading.active_count()
Returns the number of thread objects currently alive.
import threading
def simple_function():
pass
thread = threading.Thread(target=simple_function)
thread.start()
print(f"Active threads: {threading.active_count()}")
thread.join()
3. threading.Lock
Locks are used to ensure thread-safe operations on shared resources.
import threading
counter = 0
counter_lock = threading.Lock()
def increment():
global counter
with counter_lock:
temp = counter
temp += 1
counter = temp
print(f"Counter: {counter}")
threads = [threading.Thread(target=increment) for _ in range(5)]
for t in threads:
t.start()
for t in threads:
t.join()
4. threading.Timer
Used to run a function after a specified delay.
import threading
def delayed_function():
print("This is printed after a delay!")
timer = threading.Timer(3.0, delayed_function)
timer.start()
Real App Example: Multithreaded Web Scraper
A multithreaded web scraper can efficiently fetch data from multiple pages simultaneously.
The example below demonstrates using threading to scrape data concurrently.
import threading
import requests
urls = ["https://example.com/page1", "https://example.com/page2", "https://example.com/page3"]
def fetch_page(url):
try:
response = requests.get(url)
print(f"Fetched {url} with status: {response.status_code}")
except Exception as e:
print(f"Error fetching {url}: {e}")
threads = [threading.Thread(target=fetch_page, args=(url,)) for url in urls]
for thread in threads:
thread.start()
for thread in threads:
thread.join()
print("All pages fetched!")
Conclusion
Threading in Python facilitates concurrent execution, significantly enhancing the performance of I/O-bound tasks.
Understanding the threading module and its APIs unlocks new possibilities for building efficient applications.
Whether it’s ensuring thread-safe execution with Lock
or initiating delayed actions with Timer
,
threading offers indispensable tools for multithreaded programming.