Sobes.tech
Junior
240

What is multithreading and multiprocessing?

Answer from AI

sobes.tech AI

  • Multithreading: Executes multiple threads within a single process, sharing common memory. Threads are switched (context is interrupted and resumed) by the interpreter, creating an illusion of parallel execution. However, due to GIL in Python, true parallel execution of CPU-bound tasks is impossible on multi-core processors. Ideal for I/O-bound tasks (network requests, file operations) thanks to non-blocking behavior during input/output waiting.
# Example: using threads for simultaneous data downloading
import threading
import requests

def download_url(url):
    response = requests.get(url)
    print(f"Downloaded from {url}: {len(response.content)} bytes")

urls = [
    "https://www.google.com",
    "https://www.bing.com",
    "https://www.yahoo.com"
]

threads = []
for url in urls:
    thread = threading.Thread(target=download_url, args=(url,))
    threads.append(thread)
    thread.start() # Start thread

for thread in threads:
    thread.join() # Wait for thread to finish

# Output will be approximately like this (order may vary)
# Downloaded from https://www.google.com: 15379 bytes
# Downloaded from https://www.bing.com: 12345 bytes
# Downloaded from https://www.yahoo.com: 6789 bytes
  • Multiprocessing: Executes multiple processes, each with its own memory space. Each process operates independently and can utilize one or more CPU cores, overcoming GIL limitations. Ideal for CPU-bound tasks (computations, data processing) where true parallelism is important. Communication between processes is more complex than between threads (using Pipes, Queues).
# Example: using processes for parallel computations
import multiprocessing
import time

def calculate_square(number):
    time.sleep(1) # Simulate a long operation
    result = number * number
    print(f"Square of {number} is {result}")

numbers = [1, 2, 3, 4, 5]

# Creating a process pool
with multiprocessing.Pool(processes=3) as pool:
    # Applying function to list elements in parallel
    pool.map(calculate_square, numbers)

# Output may vary in order depending on the scheduler
# Square of 1 is 1
# Square of 2 is 4
# Square of 3 is 9
# ... etc.
Characteristic Multithreading Multiprocessing
GIL (Global Interpreter Lock) Limits true parallel execution of CPU-bound tasks Bypasses GIL, each process has its own interpreter
CPU Usage Ineffective for CPU-bound tasks Excellent for CPU-bound tasks
Memory Usage Threads share memory of one process Each process has its own address space
Creation/Destruction Faster and cheaper Slower and more expensive
Communication Easier (shared memory) More complex (IPC - Inter-Process Communication)
Error Isolation Error in one thread can affect the entire process Error in one process does not affect others
Application I/O-bound tasks (input/output, network) CPU-bound tasks (computations)