Introduction
A thread is the smallest unit of execution within a process. Python allows developers to create multiple threads so that different tasks can run concurrently within the same program.
Creating threads is useful when working with:
-
File Operations
-
Network Requests
-
API Calls
-
Web Scraping
-
Selenium Automation
-
Background Tasks
-
Data Processing
Python provides the built-in threading module to create and manage threads.
In this tutorial, you will learn different ways to create threads, practical examples, automation testing use cases, common mistakes, and best practices.
Importing the Threading Module
Before creating threads, import the threading module.
import threading
Method 1: Creating a Thread Using a Function
This is the most common method.
Example
import threading
def display_message():
print("Thread is running")
thread = threading.Thread(
target=display_message
)
thread.start()
Output
Thread is running
Understanding the Code
thread = threading.Thread(
target=display_message
)
| Parameter | Description |
|---|---|
| Thread() | Creates a thread object |
| target | Function executed by the thread |
Start execution using:
thread.start()
Method 2: Creating a Thread with Arguments
Example
import threading
def greet(name):
print(f"Hello {name}")
thread = threading.Thread(
target=greet,
args=("John",)
)
thread.start()
Output
Hello John
Passing Multiple Arguments
Example
import threading
def add(a, b):
print(a + b)
thread = threading.Thread(
target=add,
args=(10, 20)
)
thread.start()
Output
30
Method 3: Creating Multiple Threads
Example
import threading
def worker(number):
print(
f"Thread {number} Running"
)
for i in range(5):
thread = threading.Thread(
target=worker,
args=(i,)
)
thread.start()
Output
Thread 0 Running
Thread 1 Running
Thread 2 Running
Thread 3 Running
Thread 4 Running
(Output order may vary.)
Waiting for Threads Using join()
Example
import threading
import time
def task():
time.sleep(2)
print("Task Completed")
thread = threading.Thread(
target=task
)
thread.start()
thread.join()
print("Program Finished")
Output
Task Completed
Program Finished
Creating Multiple Threads and Waiting for Completion
Example
import threading
def worker(number):
print(
f"Thread {number} Running"
)
threads = []
for i in range(5):
thread = threading.Thread(
target=worker,
args=(i,)
)
threads.append(thread)
thread.start()
for thread in threads:
thread.join()
print("All Threads Completed")
Method 4: Creating Threads by Extending Thread Class
Python allows you to create custom thread classes.
Example
import threading
class MyThread(threading.Thread):
def run(self):
print("Custom Thread Running")
thread = MyThread()
thread.start()
Output
Custom Thread Running
Creating Multiple Custom Threads
Example
import threading
class WorkerThread(
threading.Thread
):
def __init__(self, number):
super().__init__()
self.number = number
def run(self):
print(
f"Thread {self.number}"
)
for i in range(3):
thread = WorkerThread(i)
thread.start()
Output
Thread 0
Thread 1
Thread 2
Naming Threads
Example
import threading
def worker():
print(
threading.current_thread().name
)
thread = threading.Thread(
target=worker,
name="LoginThread"
)
thread.start()
Output
LoginThread
Checking if a Thread is Alive
Example
import threading
import time
def task():
time.sleep(3)
thread = threading.Thread(
target=task
)
thread.start()
print(thread.is_alive())
Output
True
Getting Current Thread Information
Example
import threading
def worker():
print(
threading.current_thread()
)
thread = threading.Thread(
target=worker
)
thread.start()
Sample Output
<Thread(Thread-1, started)>
Daemon Threads
Daemon threads run in the background.
Example
import threading
import time
def background_task():
while True:
print("Running")
time.sleep(1)
thread = threading.Thread(
target=background_task,
daemon=True
)
thread.start()
print("Main Program Ends")
When the main program exits, daemon threads terminate automatically.
Real-World Example: Download Files Concurrently
Sequential Execution
import time
for i in range(3):
print(
f"Downloading File {i}"
)
time.sleep(2)
Time ≈ 6 seconds
Multithreaded Execution
import threading
import time
def download(file):
print(
f"Downloading {file}"
)
time.sleep(2)
for i in range(3):
thread = threading.Thread(
target=download,
args=(i,)
)
thread.start()
Time ≈ 2 seconds
Selenium Automation Example
Run multiple test cases concurrently.
import threading
def run_test(test_name):
print(
f"Running {test_name}"
)
thread1 = threading.Thread(
target=run_test,
args=("Login Test",)
)
thread2 = threading.Thread(
target=run_test,
args=("Checkout Test",)
)
thread1.start()
thread2.start()
Output
Running Login Test
Running Checkout Test
API Automation Example
Execute multiple API calls simultaneously.
import threading
import requests
def call_api(url):
response = requests.get(url)
print(
response.status_code
)
urls = [
"https://api.example.com/users",
"https://api.example.com/orders"
]
for url in urls:
thread = threading.Thread(
target=call_api,
args=(url,)
)
thread.start()
Common Mistakes Beginners Make
Forgetting start()
Incorrect
thread = threading.Thread(
target=worker
)
Thread is created but never runs.
Correct
thread.start()
Calling the Function Instead of Passing Reference
Incorrect
thread = threading.Thread(
target=worker()
)
Function executes immediately.
Correct
thread = threading.Thread(
target=worker
)
Forgetting join()
Incorrect
thread.start()
Main program may finish before thread completes.
Correct
thread.start()
thread.join()
Sharing Variables Unsafely
Multiple threads modifying the same variable may cause race conditions.
Use:
threading.Lock()
for synchronization.
Best Practices
Use Meaningful Thread Names
name="PaymentThread"
Use join() for Important Tasks
Wait for completion when necessary.
Keep Thread Tasks Small
Threads should perform a single responsibility.
Handle Exceptions Inside Threads
try:
pass
except Exception as e:
print(e)
Consider Thread Pools
For large applications use:
from concurrent.futures import ThreadPoolExecutor
Advantages of Creating Threads
-
Faster I/O operations
-
Better responsiveness
-
Concurrent task execution
-
Improved user experience
-
Efficient resource usage
Limitations
-
Global Interpreter Lock (GIL)
-
Synchronization complexity
-
Not ideal for CPU-intensive work
Conclusion
Creating threads is the first step in building concurrent Python applications. Using the threading module, developers can run multiple tasks simultaneously, improving performance and responsiveness for I/O-bound operations.
Whether you’re downloading files, calling APIs, processing data, or executing Selenium tests, understanding how to create and manage threads is an essential Python skill.
Frequently Asked Questions (FAQs)
Which module is used to create threads?
import threading
How do I create a thread?
thread = threading.Thread(
target=my_function
)
How do I start a thread?
thread.start()
How do I wait for a thread to finish?
thread.join()
Can I pass arguments to a thread?
Yes.
args=(value,)
Key Takeaways
-
Threads enable concurrent execution within a process.
-
Python provides the
threadingmodule for thread creation. -
Use
Thread()to create threads. -
Use
start()to begin execution. -
Use
join()to wait for completion. -
Arguments are passed using
args. -
Threads can be created using functions or custom classes.
-
Daemon threads run in the background.
-
Thread names improve debugging.
-
Threads are best suited for I/O-bound tasks such as Selenium automation, API calls, and file handling.
