Multithreading and Multiprocessing in Python Concurrency Programming

Concurrency refers to the ability of a program to handle multiple tasks simultaneously. In Python, the two core methods for achieving concurrency are multithreading and multiprocessing. Although both can execute tasks “in parallel”, their underlying implementations and applicable scenarios are quite different, with the key difference being the memory space isolation between processes and threads.Multithreading involves creating multiple threads within a single process, where all threads share the memory space of that process (such as global variables, file handles, etc.). This memory-sharing characteristic allows for very efficient communication between threads (e.g., passing data through global variables), but is limited by Python’s Global Interpreter Lock (GIL). The CPython interpreter stipulates that at any given time, a single CPU core can only execute one thread’s Python bytecode. This means that for I/O-bound tasks (such as network requests, file reading/writing, database queries): threads will release the GIL while waiting for I/O responses, allowing other threads to seize CPU execution, thus significantly reducing wait times and improving efficiency; for CPU-bound tasks (such as complex mathematical calculations, data encryption): threads will always occupy the CPU, and the GIL prevents threads from truly executing in parallel, resulting in additional overhead from thread switching, which can lead to worse performance than single-threaded execution.Next, let’s simulate a file download with code:

import threading
import time
def simulate_download(thread_name):    """Simulate file download (I/O-bound task)"""
    print(f"Thread {thread_name}: Starting download...")
    time.sleep(2)  # Simulate I/O wait (e.g., network transfer)
    print(f"Thread {thread_name}: Download complete")
# Create and start 3 threads
threads = []
for i in range(3):    t = threading.Thread(target=simulate_download, args=(i,))    threads.append(t)    t.start()
# Wait for all threads to finish
for t in threads:    t.join()
print("All threads have completed execution")

Three threads start almost simultaneously, with a total time of about 2 seconds (instead of 6 seconds), because threads release the GIL while <span>sleep</span> (simulating I/O wait), allowing other threads to execute in parallel.Now let’s talk about multiprocessing, which creates multiple independent processes, each with its own memory space and Python interpreter. Due to the memory isolation between processes, they are not limited by the GIL and can truly execute in parallel across multiple CPU cores. This bypasses the GIL and fully utilizes multi-core CPU resources, making it suitable for CPU-bound tasks (such as big data computations, image processing). Memory is not shared between processes, and communication must be achieved through IPC (Inter-Process Communication, such as pipes, queues), which incurs more overhead than threads.Let’s also simulate this with a code example:

import multiprocessing
import time
def simulate_calculation(process_name):    """Simulate complex calculation (CPU-bound task)"""
    print(f"Process {process_name}: Starting calculation...")
    time.sleep(2)  # Simulate CPU-bound operation (actual scenario may involve loop calculations)
    print(f"Process {process_name}: Calculation complete")
if __name__ == "__main__":  # Multiprocessing must be started in the main module to avoid code execution in child processes
    processes = []
    for i in range(3):        p = multiprocessing.Process(target=simulate_calculation, args=(i,))        processes.append(p)        p.start()
    # Wait for all processes to finish    for p in processes:        p.join()
    print("All processes have completed execution")

Three processes execute in parallel on different CPU cores, with a total time of about 2 seconds, fully utilizing multi-core resources.From the above content, I believe you have gained a certain understanding of both multiprocessing and multithreading. When to choose the appropriate method for a given scenario, feel free to try it out yourself.

Leave a Comment