Python

P
PythonHub
Progress 0%

Python

  • Home
  • History of Python
  • Applications of Python
  • Introduction To Python
    • What is Python
    • Character Set
    • Tokens in Python
    • Python Execution Mode
    • Variable And Identifiers
    • Data Types in Python
    • Operators And Expressions
    • Constants in Python
    • Assignment Statement
    • Input / Output in Python
    • Simple Python Scripts
    • Namespace in Python
    • πŸ“ Assignments
  • Operators in Python
    • Arithmetic Operators
    • Assignment Operators
    • Shorthand Assignment Operators
    • Relational Operators
    • Logical Operators
    • Bitwise Operators
    • Special Operators
    • πŸ“ Assignments
  • Input Output in Python
    • Accept Input
    • Output Formatting
    • πŸ“ Assignments
  • Conditional Statement
    • Decision Making
    • if Statement
    • IF-ELSE STATEMENT
    • IF-ELSE LADDER
    • NESTED IF-ELSE
    • Short Hand IF-ELSE
    • πŸ“ Assignments
  • Loops
    • Introduction to Loops
    • While Loop
    • Nested While Loop
    • πŸ“ While Loop Assignments
    • For Loop
    • For Loop Examples
    • Nested For Loop
    • Nested For Loop Examples
    • Infinite While Loops
    • Infinite For Loops
    • Break, Continue and Else in Loops
    • Difference Between For and While Loop
    • For Each Loop
    • πŸ“ For Each Assignments
    • πŸ“ All Loops Assignments
  • List
    • List in Python
    • Access List Elements
    • List Functions
    • Iterate (Loop) List
    • List Comprehension
    • πŸ“ Assignments
  • Tuple
    • Tuple in Python
    • Access Tuple Elements
    • Tuple Functions
    • Iterate (Loop) Tuple
    • Unpack Tuple
    • Tuple Comprehension
    • πŸ“ Assignments
  • Set
    • Set in Python
    • Access Set Elements
    • Set Methods
    • Iterate (Loop) Set
    • Pack/Unpack Set
    • Set Comprehension
    • πŸ“ Assignments
  • Dictionary
    • Dictionary
    • Access Dictionary Items
    • Dictionary Methods
    • Iterate (Loop) Dictionary
    • Formatting Dictionaries
    • Nested Dictionaries
    • Dictionary Comprehension
    • πŸ“ Assignments
  • Diff List Tuple Set Dictionary
    • List vs Tuple
    • List vs Set
    • List vs Dictionary
    • Tuple vs Set
    • Tuple vs Dictionary
    • Dictionary vs Set
    • πŸ“ Assignments
  • Exception
    • Error vs Exception
    • Types of Exception
    • Exception Handling
    • User Defined Exception
    • Logging Exception
    • πŸ“ Assignments
  • Functions
    • Introduction to Functions
    • Modular Programming
    • Types of Functions
    • Inbuilt Functions
    • Need For User-Defined Function
    • Elements of User Defined Function
    • Function Arguments
    • Nesting of Functions
    • Recursion
    • Global Local and Non Local
    • Python Lambda Functions
    • πŸ“ Assignments
  • Python Module
    • Introduction to Module
    • Inbuilt Modules in Python
    • User Defined Module
    • πŸ“ Assignments
  • File Handling
    • Introduction to Files
    • Create File
    • Read Files
    • Write to File
    • Rename File
    • Copy File
    • Move File
    • List Files in Directory
    • Binary Files
    • Zipping and Unzipping Files
    • πŸ“ Assignments
  • Strings
    • Basics of Strings
    • String Special Operators
    • String Formatting Operators
    • String Methods
    • πŸ“ Assignments
  • Regular Expressions
  • Python OOPS
    • Basics of Object Oriented
    • What are Classes and Objects?
    • Creating Class and Object
    • OOP vs Procedural Programming
    • Difference Between Classes and Objects
    • Constructors
    • Destructor
    • Built Class Methods and Attributes
    • Class and Instance Variables
    • Inheritance in Python
    • Single Inheritance
    • Multiple Inheritance
    • Multilevel Inheritance
    • Hierarchical Inheritance
    • Hybrid Inheritance
    • Abstraction
    • Method Overriding
    • Abstract Method
    • Interfaces in Python
    • Abstract Class vs Interface
    • Public, Private and Protected
    • Overloading vs Overriding
    • Inheritance vs Composition
    • Encapsulation
    • Polymorphism
    • Inner Classes
    • πŸ“ Assignments
  • Advanced Python
    • Iterator in Python
    • Generator in Python
    • Decorator in Python
    • Type Hints in Python
    • Async/Await Programming
    • Dataclasses in Python
    • Context Managers in Python
    • Property Decorator in Python
    • __slots__ in Python
    • Enums in Python
    • Walrus Operator in Python
    • Match-Case in Python
    • πŸ“ Assignments
  • Python Standard Library
    • Collections Module
    • Itertools Module
    • Functools Module
    • Datetime Module
    • JSON Module
    • OS Module
    • Sys Module
    • Random Module
    • Math Module
    • πŸ“ Assignments
  • Python Testing
    • Unit Testing in Python
    • Pytest Framework
    • Mocking in Python
    • πŸ“ Assignments
  • Python Best Practices
    • PEP 8 Style Guide
    • Docstrings in Python
    • Logging in Python
    • Code Optimization Tips
    • Debugging Techniques
    • πŸ“ Assignments
  • MySQL Database in Python
    • Introduction to MySQL with Python
    • DBMS vs File System
    • Connecting to MySQL Database
    • Create Database in MySQL
    • Create Table in MySQL
    • Insert Data in MySQL
    • Insert Multiple Rows
    • Select Data from MySQL
    • WHERE Clause in MySQL
    • Update Data in MySQL
    • Delete Data from MySQL
    • Parameterized Queries
    • Transaction Management
    • Error Handling
    • Connection Pooling
    • MySQL Drivers Guide
    • Joins in MySQL
    • Aggregation Functions
    • Backup MySQL Database
    • Best Practices
    • πŸ“ Assignments
  • MySQL Database Operations
    • SELECT Statement
    • MySQL Operators
    • DDL Statements
    • DML Statements
    • Subqueries
    • JOIN Operations
    • Aggregation
    • Case Study
    • πŸ“ Assignments
  • Graphics in Python
  • Threads in Python
    • Introduction to Threads
    • Process vs Threads
    • Concurrent Programming & GIL
    • Uses of Threads
    • Creating Threads
    • Single Tasking
    • Multi Tasking
    • Thread Synchronization
    • πŸ“ Assignments
  • Interview Questions & Answers
  • Python Case Studies
  • Multiple Choice Questions
  • πŸ“ Practice Problems
Get in Touch
  • tech2dsm@gmail.com

© Sankalan Data Tech

Python Language Interactive Tutorial

Python: Uses of Threads

Python Uses of Threads - Complete Guide

Learn practical real-world applications of threads in Python.

Created by Sankalan Data Tech Team Verified
Data Engineers, Analysts, Scientists & Trainers
Created by experienced Python developers, data engineers, and data scientists to make programming easy through practical examples, real-world experience, and clear explanations.
Read Time: 10 minutes Level: Intermediate Topic: Python Threading Focus: Real-World Applications
On this page:
  • Why Threads Matter
  • Web Scraping
  • Download Managers
  • GUI Applications
  • Database Operations
  • API Calls
  • Background Processing
  • Real-World Example
  • Best Practices
  • Try It Yourself
  • Quiz
  • FAQ
Share this tutorial:
Twitter LinkedIn Facebook WhatsApp Reddit Telegram Email Copy Link
What You'll Learn Here
  • Web scraping β€” fetching multiple pages concurrently
  • Download managers β€” downloading multiple files at once
  • GUI applications β€” keeping UI responsive
  • Database operations β€” running multiple queries
  • API calls β€” making multiple requests in parallel
  • Background processing β€” tasks running in the background

Why Threads Matter

Threads are useful in many real-world applications. They help you do multiple things at once, making your programs faster and more responsive.

⚑ Think of it like a restaurant kitchen.

Without threads: One chef does everything β€” takes orders, cooks, cleans. Everything is slow.

With threads: Multiple chefs work simultaneously β€” one takes orders, another cooks, another cleans. Everything is fast and efficient!

Web Scraping

Fetch multiple web pages at the same time

Download Managers

Download multiple files in parallel

GUI Applications

Keep the user interface responsive

Database Operations

Run multiple queries concurrently

API Calls

Make multiple API requests at once

Background Processing

Run tasks in the background

πŸ’‘ Key concept: Threads are ideal for I/O-bound tasks where the program waits for external resources like network, disk, or user input.

1

When to Use Threads

# ============================================================
# WHEN TO USE THREADS
# ============================================================

print("""
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ USE THREADS FOR:                                              β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ 1. Network operations (web requests, API calls)              β”‚
β”‚ 2. File I/O (reading/writing files)                          β”‚
β”‚ 3. Database queries                                          β”‚
β”‚ 4. User interface interactions                                β”‚
β”‚ 5. Background tasks (logging, monitoring)                    β”‚
β”‚ 6. Batch processing (multiple similar tasks)                 β”‚
β”‚                                                                 β”‚
β”‚ AVOID THREADS FOR:                                            β”‚
β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ 1. CPU-intensive calculations                                 β”‚
β”‚ 2. Heavy numerical processing                                 β”‚
β”‚ 3. Tasks that need true parallelism                          β”‚
β”‚ 4. Work that doesn't involve waiting                         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
""")

Key point: Threads are best when your program spends time waiting for external resources.

Quick Check: What type of tasks are threads best for? (Answer: I/O-bound tasks that involve waiting)

Web Scraping

2

Fetching Multiple Pages Concurrently

Web scraping involves fetching data from websites. Without threads, you fetch one page at a time. With threads, you can fetch multiple pages simultaneously.

# ============================================================
# WEB SCRAPING WITH THREADS
# ============================================================

import threading
import time
import random

# ============================================================
# SIMULATED WEB SCRAPING
# ============================================================

def fetch_page(url):
    """Simulate fetching a web page"""
    thread_name = threading.current_thread().name
    print(f"[{thread_name}] Fetching: {url}")
    
    # Simulate network delay
    delay = random.uniform(0.5, 1.5)
    time.sleep(delay)
    
    # Simulate page content
    content = f"Content from {url} (took {delay:.2f}s)"
    print(f"[{thread_name}] Done: {url}")
    return content

def scrape_pages(urls):
    """Scrape multiple pages using threads"""
    threads = []
    results = {}
    
    def scrape_one(url):
        results[url] = fetch_page(url)
    
    # Create and start threads
    for url in urls:
        t = threading.Thread(target=scrape_one, args=(url,))
        threads.append(t)
        t.start()
    
    # Wait for all threads
    for t in threads:
        t.join()
    
    return results

print("=" * 60)
print("WEB SCRAPING WITH THREADS")
print("=" * 60)

# List of URLs to scrape
urls = [
    "https://example.com/page1",
    "https://example.com/page2",
    "https://example.com/page3",
    "https://example.com/page4",
    "https://example.com/page5"
]

print(f"Scraping {len(urls)} pages...")

# Scrape without threads (sequential)
print("\n1. SEQUENTIAL SCRAPING:")
start = time.time()
for url in urls:
    fetch_page(url)
sequential_time = time.time() - start
print(f"Sequential time: {sequential_time:.2f}s")

# Scrape with threads (parallel)
print("\n2. PARALLEL SCRAPING:")
start = time.time()
results = scrape_pages(urls)
parallel_time = time.time() - start
print(f"Parallel time: {parallel_time:.2f}s")

print(f"\nSpeedup: {sequential_time/parallel_time:.2f}x")

print("""
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ BENEFITS OF THREADED WEB SCRAPING:                            β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ β€’ Multiple pages fetched at the same time                     β”‚
β”‚ β€’ Total time = time of slowest page (not sum of all)          β”‚
β”‚ β€’ Much faster for many pages                                   β”‚
β”‚ β€’ Simple to implement with threads                            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
""")

Web scraping key points:

  • Parallel fetching β€” multiple pages at once
  • Speedup β€” total time = slowest page
  • Simple β€” easy to implement
  • Scalable β€” can handle many pages

Quick Check: Why is threading useful for web scraping? (Answer: It allows fetching multiple pages at the same time)

Download Managers

3

Downloading Multiple Files Simultaneously

# ============================================================
# DOWNLOAD MANAGER WITH THREADS
# ============================================================

import threading
import time
import random
import os

# ============================================================
# SIMULATED DOWNLOAD MANAGER
# ============================================================

class DownloadManager:
    """Download multiple files using threads"""
    
    def __init__(self):
        self.downloads = []
        self.completed = 0
        self.lock = threading.Lock()
    
    def download_file(self, file_name, size_mb):
        """Simulate downloading a file"""
        thread_name = threading.current_thread().name
        
        print(f"[{thread_name}] Starting download: {file_name} ({size_mb}MB)")
        self.downloads.append(file_name)
        
        # Simulate download progress
        for progress in range(0, 101, 20):
            time.sleep(random.uniform(0.2, 0.5))
            print(f"[{thread_name}] {file_name}: {progress}% complete")
        
        # Thread-safe counter update
        with self.lock:
            self.completed += 1
        
        print(f"[{thread_name}] Completed: {file_name}")
        return file_name
    
    def start_downloads(self, files):
        """Start multiple downloads in parallel"""
        threads = []
        start_time = time.time()
        
        for file_name, size in files:
            t = threading.Thread(
                target=self.download_file,
                args=(file_name, size),
                name=f"Download-{file_name[:5]}"
            )
            threads.append(t)
            t.start()
        
        # Wait for all downloads
        for t in threads:
            t.join()
        
        end_time = time.time()
        
        print(f"\nAll downloads completed!")
        print(f"Total files: {len(files)}")
        print(f"Total time: {end_time - start_time:.2f}s")
        print(f"Files: {', '.join(self.downloads)}")

print("=" * 60)
print("DOWNLOAD MANAGER WITH THREADS")
print("=" * 60)

# Files to download (name, size in MB)
files = [
    ("movie.mp4", 150),
    ("document.pdf", 5),
    ("music.mp3", 10),
    ("image.jpg", 3),
    ("game.exe", 500)
]

manager = DownloadManager()
manager.start_downloads(files)

print("""
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ BENEFITS OF THREADED DOWNLOAD MANAGER:                        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ β€’ Multiple files download simultaneously                      β”‚
β”‚ β€’ Total time = time of largest file (not sum of all)          β”‚
β”‚ β€’ Progress tracking for each file                             β”‚
β”‚ β€’ User interface remains responsive                           β”‚
β”‚ β€’ Can pause/resume individual downloads                      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
""")

Download manager key points:

  • Parallel downloads β€” multiple files at once
  • Time savings β€” total time reduced
  • Progress tracking β€” each file monitored
  • Responsive β€” UI remains usable

Quick Check: How does a threaded download manager improve performance? (Answer: By downloading multiple files simultaneously)

GUI Applications

4

Keeping Your UI Responsive

# ============================================================
# GUI APPLICATIONS WITH THREADS
# ============================================================

import threading
import time
import tkinter as tk

# ============================================================
# SIMPLE GUI WITH BACKGROUND THREAD
# ============================================================

class ResponsiveGUI:
    """GUI application that stays responsive"""
    
    def __init__(self):
        self.root = tk.Tk()
        self.root.title("Responsive GUI")
        self.root.geometry("300x200")
        
        # Status label
        self.status = tk.Label(self.root, text="Ready", font=("Arial", 12))
        self.status.pack(pady=20)
        
        # Start button
        self.start_btn = tk.Button(
            self.root,
            text="Start Task",
            command=self.start_task,
            font=("Arial", 12)
        )
        self.start_btn.pack(pady=10)
        
        # Stop button
        self.stop_btn = tk.Button(
            self.root,
            text="Stop",
            command=self.stop_task,
            font=("Arial", 12)
        )
        self.stop_btn.pack(pady=10)
        
        self.task_running = False
    
    def start_task(self):
        """Start a background task"""
        if self.task_running:
            return
        
        self.task_running = True
        self.status.config(text="Task running...")
        self.start_btn.config(state=tk.DISABLED)
        
        # Start background thread
        t = threading.Thread(target=self.long_task)
        t.daemon = True
        t.start()
    
    def long_task(self):
        """Simulate a long-running task"""
        for i in range(1, 11):
            if not self.task_running:
                break
            # Update UI from main thread
            self.root.after(0, self.update_status, i)
            time.sleep(0.5)
        
        self.root.after(0, self.task_complete)
    
    def update_status(self, progress):
        """Update status label"""
        self.status.config(text=f"Task: {progress*10}% complete")
    
    def task_complete(self):
        """Handle task completion"""
        self.task_running = False
        self.status.config(text="Task complete!")
        self.start_btn.config(state=tk.NORMAL)
    
    def stop_task(self):
        """Stop the running task"""
        self.task_running = False
        self.status.config(text="Task stopped")
        self.start_btn.config(state=tk.NORMAL)
    
    def run(self):
        self.root.mainloop()

# ============================================================
# RUN THE GUI
# ============================================================

print("=" * 60)
print("GUI APPLICATIONS WITH THREADS")
print("=" * 60)

print("""
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ BENEFITS OF THREADS IN GUI APPLICATIONS:                      β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ β€’ UI stays responsive during long tasks                       β”‚
β”‚ β€’ User can interact with the interface                        β”‚
β”‚ β€’ No "Not Responding" messages                               β”‚
β”‚ β€’ Can cancel/stop tasks                                      β”‚
β”‚ β€’ Better user experience                                      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
""")

print("""
NOTE: To run the GUI example, uncomment the code and run it locally.
This demonstrates how threads keep the UI responsive.
""")

# Uncomment to run the GUI:
# app = ResponsiveGUI()
# app.run()

GUI key points:

  • Responsive UI β€” no freezing
  • Background tasks β€” run in separate threads
  • User interaction β€” can cancel tasks
  • Better experience β€” professional feel

Quick Check: Why use threads in GUI applications? (Answer: To keep the UI responsive during long operations)

Database Operations

5

Running Multiple Queries Concurrently

# ============================================================
# DATABASE OPERATIONS WITH THREADS
# ============================================================

import threading
import time
import random

# ============================================================
# SIMULATED DATABASE OPERATIONS
# ============================================================

class DatabaseThread:
    """Simulate database operations with threads"""
    
    def __init__(self):
        self.results = {}
        self.lock = threading.Lock()
    
    def run_query(self, query_id, query_type, delay):
        """Simulate a database query"""
        thread_name = threading.current_thread().name
        
        print(f"[{thread_name}] Running query {query_id}: {query_type}")
        time.sleep(delay)
        
        result = f"Result from query {query_id} ({query_type})"
        
        with self.lock:
            self.results[query_id] = result
        
        print(f"[{thread_name}] Query {query_id} completed")
        return result
    
    def run_queries(self, queries):
        """Run multiple queries in parallel"""
        threads = []
        
        for query_id, query_type, delay in queries:
            t = threading.Thread(
                target=self.run_query,
                args=(query_id, query_type, delay),
                name=f"DB-{query_id}"
            )
            threads.append(t)
            t.start()
        
        for t in threads:
            t.join()
        
        return self.results

print("=" * 60)
print("DATABASE OPERATIONS WITH THREADS")
print("=" * 60)

db = DatabaseThread()

# Simulated queries: (id, type, delay in seconds)
queries = [
    (1, "SELECT * FROM users", 0.5),
    (2, "SELECT * FROM orders", 0.8),
    (3, "SELECT * FROM products", 0.3),
    (4, "SELECT * FROM customers", 0.6),
    (5, "SELECT * FROM inventory", 0.4)
]

print("Running 5 database queries in parallel...")
start = time.time()

# Run queries in parallel
results = db.run_queries(queries)
total_time = time.time() - start

print(f"\nAll queries completed!")
print(f"Total time: {total_time:.2f}s")
print(f"Queries: {len(results)}")

for query_id, result in results.items():
    print(f"  Query {query_id}: {result}")

print("""
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ BENEFITS OF THREADED DATABASE OPERATIONS:                     β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ β€’ Multiple queries run in parallel                            β”‚
β”‚ β€’ Total time = time of slowest query (not sum of all)         β”‚
β”‚ β€’ Database connections can be pooled                         β”‚
β”‚ β€’ Better resource utilization                                β”‚
β”‚ β€’ Faster overall execution                                   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
""")

Database operations key points:

  • Parallel queries β€” multiple queries at once
  • Time savings β€” total time reduced
  • Connection pooling β€” efficient resource use
  • Faster reports β€” quicker data access

Quick Check: Why use threads for database queries? (Answer: To run multiple queries in parallel and reduce total time)

API Calls

6

Making Multiple API Requests in Parallel

# ============================================================
# API CALLS WITH THREADS
# ============================================================

import threading
import time
import random
import json

# ============================================================
# SIMULATED API CALLS
# ============================================================

def make_api_call(endpoint, data):
    """Simulate making an API call"""
    thread_name = threading.current_thread().name
    
    print(f"[{thread_name}] Calling: {endpoint}")
    
    # Simulate network delay
    delay = random.uniform(0.3, 1.0)
    time.sleep(delay)
    
    # Simulate response
    response = {
        "endpoint": endpoint,
        "data": data,
        "status": "success",
        "timestamp": time.time(),
        "delay": delay
    }
    
    print(f"[{thread_name}] Response received from {endpoint}")
    return response

def call_apis(api_list):
    """Call multiple APIs in parallel"""
    threads = []
    results = {}
    
    def call_one(endpoint, data):
        results[endpoint] = make_api_call(endpoint, data)
    
    for endpoint, data in api_list:
        t = threading.Thread(
            target=call_one,
            args=(endpoint, data),
            name=f"API-{endpoint[:10]}"
        )
        threads.append(t)
        t.start()
    
    for t in threads:
        t.join()
    
    return results

print("=" * 60)
print("API CALLS WITH THREADS")
print("=" * 60)

# APIs to call: (endpoint, data)
apis = [
    ("users/get", {"user_id": 1}),
    ("orders/list", {"limit": 10}),
    ("products/search", {"query": "laptop"}),
    ("customers/profile", {"customer_id": 5}),
    ("inventory/check", {"product_id": 100})
]

print("Calling 5 APIs in parallel...")
start = time.time()

# Call APIs in parallel
results = call_apis(apis)
total_time = time.time() - start

print(f"\nAll APIs called!")
print(f"Total time: {total_time:.2f}s")
print(f"APIs: {len(results)}")

for endpoint, response in results.items():
    print(f"  {endpoint}: {response['status']} (took {response['delay']:.2f}s)")

print("""
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ BENEFITS OF THREADED API CALLS:                               β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ β€’ Multiple APIs called simultaneously                         β”‚
β”‚ β€’ Total time = time of slowest API (not sum of all)           β”‚
β”‚ β€’ Better user experience (faster responses)                   β”‚
β”‚ β€’ Can aggregate data from multiple sources                    β”‚
β”‚ β€’ Efficient resource utilization                             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
""")

API calls key points:

  • Parallel requests β€” multiple APIs at once
  • Faster responses β€” total time reduced
  • Data aggregation β€” combine results
  • Better UX β€” faster loading times

Quick Check: Why use threads for API calls? (Answer: To make multiple API requests in parallel and reduce total time)

Background Processing

7

Running Tasks in the Background

# ============================================================
# BACKGROUND PROCESSING WITH THREADS
# ============================================================

import threading
import time
import queue

# ============================================================
# BACKGROUND TASK QUEUE
# ============================================================

class BackgroundProcessor:
    """Process tasks in the background"""
    
    def __init__(self):
        self.task_queue = queue.Queue()
        self.results = []
        self.running = True
        self.worker_thread = None
    
    def start(self):
        """Start the background worker"""
        self.worker_thread = threading.Thread(target=self._worker)
        self.worker_thread.daemon = True
        self.worker_thread.start()
        print("Background worker started")
    
    def stop(self):
        """Stop the background worker"""
        self.running = False
        if self.worker_thread:
            self.worker_thread.join(timeout=1)
        print("Background worker stopped")
    
    def add_task(self, task_name, task_func, *args):
        """Add a task to the queue"""
        self.task_queue.put((task_name, task_func, args))
        print(f"Task added: {task_name}")
    
    def _worker(self):
        """Background worker thread"""
        while self.running:
            try:
                # Get task from queue (with timeout)
                task_name, task_func, args = self.task_queue.get(timeout=1)
                
                print(f"Processing: {task_name}")
                result = task_func(*args)
                self.results.append((task_name, result))
                print(f"Completed: {task_name}")
                
                self.task_queue.task_done()
                
            except queue.Empty:
                # No tasks, continue
                continue
            except Exception as e:
                print(f"Error processing task: {e}")
    
    def get_results(self):
        """Get all results"""
        return self.results

# ============================================================
# SAMPLE TASKS
# ============================================================

def process_file(file_name):
    """Simulate processing a file"""
    time.sleep(0.5)
    return f"Processed {file_name}"

def send_email(recipient, subject):
    """Simulate sending an email"""
    time.sleep(0.3)
    return f"Email sent to {recipient}: {subject}"

def generate_report(report_type):
    """Simulate generating a report"""
    time.sleep(0.8)
    return f"Generated {report_type} report"

print("=" * 60)
print("BACKGROUND PROCESSING WITH THREADS")
print("=" * 60)

# Create background processor
processor = BackgroundProcessor()
processor.start()

# Add tasks
print("\nAdding tasks to background queue...")
processor.add_task("File A", process_file, "data.csv")
processor.add_task("File B", process_file, "report.pdf")
processor.add_task("Email", send_email, "admin@example.com", "Daily Report")
processor.add_task("Report", generate_report, "Sales")

# Wait for tasks to complete
print("\nWaiting for tasks to complete...")
time.sleep(4)

# Stop the processor
processor.stop()

# Get results
print("\nResults:")
for task_name, result in processor.get_results():
    print(f"  {task_name}: {result}")

print("""
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ BENEFITS OF BACKGROUND PROCESSING:                            β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ β€’ Tasks run in the background                                 β”‚
β”‚ β€’ Main program continues working                             β”‚
β”‚ β€’ Tasks are queued and processed asynchronously              β”‚
β”‚ β€’ No blocking of main thread                                 β”‚
β”‚ β€’ Can handle multiple tasks efficiently                      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
""")

Background processing key points:

  • Asynchronous β€” tasks run in background
  • Queued β€” tasks are processed in order
  • Non-blocking β€” main thread continues
  • Scalable β€” can handle many tasks

Quick Check: What is background processing used for? (Answer: Running tasks without blocking the main program)

Real-World Example

8

Complete Real-World Application

# ============================================================
# COMPLETE REAL-WORLD APPLICATION
# ============================================================

import threading
import time
import random
import json

class DataProcessor:
    """Complete data processing application with threads"""
    
    def __init__(self):
        self.tasks = []
        self.results = []
        self.lock = threading.Lock()
    
    # ============================================================
    # TASK FUNCTIONS
    # ============================================================
    
    def fetch_data(self, source):
        """Fetch data from a source"""
        time.sleep(random.uniform(0.3, 0.7))
        return f"Data from {source}"
    
    def process_data(self, data):
        """Process the fetched data"""
        time.sleep(random.uniform(0.2, 0.5))
        return f"Processed: {data}"
    
    def save_data(self, data):
        """Save processed data"""
        time.sleep(random.uniform(0.1, 0.3))
        return f"Saved: {data}"
    
    # ============================================================
    # WORKFLOW FUNCTIONS
    # ============================================================
    
    def run_workflow(self, source):
        """Complete workflow with threads"""
        print(f"\nProcessing source: {source}")
        
        # Step 1: Fetch data
        data = self.fetch_data(source)
        print(f"  Fetched from {source}")
        
        # Step 2: Process data
        processed = self.process_data(data)
        print(f"  Processed data")
        
        # Step 3: Save data
        saved = self.save_data(processed)
        print(f"  Saved data")
        
        return saved
    
    def run_parallel_workflows(self, sources):
        """Run multiple workflows in parallel"""
        threads = []
        results = {}
        
        def run_one(source):
            results[source] = self.run_workflow(source)
        
        print("Starting parallel workflows...")
        start = time.time()
        
        for source in sources:
            t = threading.Thread(target=run_one, args=(source,))
            threads.append(t)
            t.start()
        
        for t in threads:
            t.join()
        
        end = time.time()
        
        print(f"\nAll workflows completed in {end - start:.2f}s")
        return results

# ============================================================
# DEMONSTRATION
# ============================================================

print("=" * 60)
print("COMPLETE REAL-WORLD APPLICATION")
print("=" * 60)

processor = DataProcessor()

# Sources to process
sources = ["Database", "API", "File System", "Web Service", "Cache"]

print("Processing 5 sources...\n")

# Run parallel workflows
results = processor.run_parallel_workflows(sources)

print("\nResults:")
for source, result in results.items():
    print(f"  {source}: {result}")

print("""
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ WHAT THIS APPLICATION DEMONSTRATES:                            β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ 1. Real-world data processing pipeline                         β”‚
β”‚ 2. Multiple sources processed in parallel                     β”‚
β”‚ 3. Each workflow: Fetch β†’ Process β†’ Save                     β”‚
β”‚ 4. Threads for each source                                    β”‚
β”‚ 5. Results collected and displayed                            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
""")

Real-world example key points:

  • Complete workflow β€” fetch, process, save
  • Parallel processing β€” multiple sources
  • Thread safety β€” locks for shared data
  • Real-world β€” practical application

Quick Check: What makes this a real-world example? (Answer: It shows a complete data processing pipeline with parallel workflows)

Best Practices

9

Best Practices for Using Threads

# ============================================================
# BEST PRACTICES FOR THREADS
# ============================================================

print("1. USE THREADS FOR I/O-BOUND TASKS")
print("   - Network operations, file I/O, database queries")
print("   - Not for CPU-intensive work")

print("\n2. USE THREAD POOLS FOR MANY TASKS")
print("   - from concurrent.futures import ThreadPoolExecutor")
print("   - Reuses threads efficiently")

print("\n3. USE QUEUES FOR THREAD COMMUNICATION")
print("   - from queue import Queue")
print("   - Thread-safe communication")

print("\n4. USE LOCKS FOR SHARED DATA")
print("   - from threading import Lock")
print("   - Prevent race conditions")

print("\n5. HANDLE EXCEPTIONS IN THREADS")
print("   - Exceptions in threads don't propagate to main")
print("   - Use try/except inside thread functions")

print("\n6. LIMIT THE NUMBER OF THREADS")
print("   - Too many threads = performance degradation")
print("   - Use pools to manage limits")

print("\n7. USE DAEMON THREADS CAREFULLY")
print("   - Use for background tasks")
print("   - Don't use for critical work")

print("\n8. ALWAYS JOIN THREADS")
print("   - Ensure threads complete before program exits")
print("   - Prevents resource leaks")

Best practices summary:

  • Use for I/O β€” not CPU work
  • Use pools β€” manage many threads
  • Use queues β€” thread-safe communication
  • Use locks β€” prevent race conditions

Quick Check: What should you use for thread-safe communication? (Answer: Queue)

Try It Yourself

Experiment with different uses of threads in the editor below.

Loading Pyodide... 0%
Python Code Editor
========================================
USES OF THREADS - PRACTICE
========================================

1. WEB SCRAPING SIMULATION
----------------------------------------
Scraping 3 pages in parallel...
Page 1: Started
Page 2: Started
Page 3: Started
Page 3: Completed
Page 1: Completed
Page 2: Completed

2. DOWNLOAD MANAGER SIMULATION
----------------------------------------
Downloading 3 files in parallel...
movie.mp4: Starting download (150MB)
document.pdf: Starting download (5MB)
music.mp3: Starting download (10MB)
music.mp3: Download complete!
document.pdf: Download complete!
movie.mp4: Download complete!

3. USES OF THREADS SUMMARY
----------------------------------------
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ USE CASE β”‚ BENEFIT β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Web Scraping β”‚ Fetch multiple pages in parallel β”‚
β”‚ Download Manager β”‚ Download multiple files at once β”‚
β”‚ GUI Applications β”‚ Keep UI responsive β”‚
β”‚ Database Queries β”‚ Run multiple queries concurrently β”‚
β”‚ API Calls β”‚ Make multiple requests in parallel β”‚
β”‚ Background Tasks β”‚ Process tasks without blocking β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

4. RECOMMENDATIONS
----------------------------------------
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Scenario β”‚ Recommended Approach β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Web scraping many pages β”‚ Use ThreadPoolExecutor β”‚
β”‚ Downloading files β”‚ Use threading with progress trackingβ”‚
β”‚ Keeping UI responsive β”‚ Use threading for background tasks β”‚
β”‚ Multiple DB queries β”‚ Use threading with connection pools β”‚
β”‚ Many API calls β”‚ Use ThreadPoolExecutor β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Threads make many real-world applications faster and more responsive!
πŸ†

You've Got It!

You now understand the practical uses of threads in Python. You know how to apply threading to web scraping, download managers, GUI applications, and more.

Quick Quiz

Test what you've learned:

1. What type of tasks are threads best for?
2. Why use threads for web scraping?
3. How do threads help GUI applications?
4. What should you use for thread-safe communication?
5. What is a common use of threads in real-world applications?

Frequently Asked Questions

What is the most common use of threads? β–Ό

The most common use of threads is for I/O-bound tasks like web scraping, downloading files, and keeping GUI applications responsive. Threads excel when your program spends time waiting for external resources.

Can I use threads for CPU-intensive tasks? β–Ό

You can, but it's not recommended. The GIL limits the performance of CPU-bound threads. For CPU-intensive tasks, use multiprocessing instead of threading.

What is a common interview question about thread uses? β–Ό

Common questions include: "What are the practical uses of threads in Python?" "When would you use threading vs multiprocessing?" and "How do threads improve web scraping performance?"

What is the difference between threads and asyncio? β–Ό

Threads use OS-level threads and are good for I/O-bound tasks with blocking operations. asyncio uses an event loop and is good for high-concurrency I/O operations with non-blocking patterns.

How many threads should I create? β–Ό

A good rule of thumb is to create threads equal to the number of CPU cores for CPU-bound tasks. For I/O-bound tasks, you can create more threads (10-100) since they spend time waiting. Use ThreadPoolExecutor to manage thread counts automatically.

Where to Go From Here

Now that you understand the uses of threads, check out these related topics:

Creating Threads

Deep dive into creating and managing threads.

Learn More β†’

Single Tasking

Learn about single-threaded execution.

Learn More β†’

Multi Tasking

Learn about concurrent execution.

Learn More β†’
Interview Resources
  • Python Syntax & Variables Interview Questions
  • Top SQL Interview Questions & Answers
  • SQL Joins: Displaying Data from Multiple Tables FAQ
  • Python Lists and Dictionaries Interview Questions
  • Python OOP Interview Questions
  • SQL Set Operators Interview Questions
Previous: Concurrent Programming & GIL Next: Creating Threads β†’