Python Multithreading: How to Use Threads & Multiprocessing

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction to Multithreading and Multiprocessing in Python

When building modern applications, you often need to boost performance. This is achieved by running tasks in parallel. In Python, tools like multithreading and multiprocessing help you do exactly that. Despite the Global Interpreter Lock (GIL), multithreading in Python can significantly speed up your programs. This is especially true for I/O-bound tasks, such as network requests or file operations.

In this guide, we'll break down how multithreading works in Python. We'll explore the threading library, compare it with multiprocessing, and walk through practical examples. This will help you optimize your code for faster execution.

What Is Multithreading in Python?

Multithreading in Python lets you run multiple threads within a single process. Each thread executes a portion of your code concurrently. This approach is highly effective for tasks that involve waiting for external resources.

Benefits of Multithreading for I/O-Bound Tasks

Multithreading speeds up programs when tasks include:

  • Network requests, such as fetching data from the internet.
  • File operations, including reading and writing.
  • Database queries.
  • Other I/O operations where the CPU sits idle waiting.

However, multithreading has its limits. Python has the Global Interpreter Lock (GIL), which prevents multiple threads from executing Python bytecode simultaneously. Because of this, multithreading isn't ideal for CPU-intensive tasks that need full processor utilization.

When to Use Multithreading vs Multiprocessing

Choosing between multithreading and multiprocessing depends on the type of tasks you're handling. Multithreading works best for waiting scenarios, while multiprocessing is built for heavy computations.

Scenario Recommendations

  • I/O-bound tasks: Use threading to avoid blocking the main thread.
  • CPU-bound tasks: Use multiprocessing to bypass the GIL and leverage multiple CPU cores.
  • Working with network APIs: Choose threading for efficient request handling.
  • Parallel data processing: Use multiprocessing to distribute the workload across processors.

This approach helps you avoid wasting resources and makes your program run faster.

The Threading Library: Basics and Examples

Python's threading library provides tools for creating and managing threads. It's easy to use and perfect for beginners.

Simple Thread Creation Example

Here's a basic multithreading example in Python:

import threading
import time

def print_numbers():
    for i in range(5):
        print(f"Number: {i}")
        time.sleep(1)

# Create a thread
thread = threading.Thread(target=print_numbers)
thread.start()

# Main thread continues
print("Main thread finished!")

In this code, the main thread finishes immediately, while the print_numbers function runs in a separate thread. This shows how multithreading lets you keep working without waiting.

Passing Arguments to a Thread

To pass data into a thread's function, use the args parameter:

def greet(name):
    print(f"Hello, {name}!")

thread = threading.Thread(target=greet, args=("Alice",))
thread.start()

Here, the argument "Alice" is passed to the greet function. This is useful for parameterizing tasks within threads.

Waiting for Threads to Finish with join

The join method lets you wait for a thread to complete before continuing:

Blogs

Book Recommendations