Skip to main content
  1. Posts/

Threaded Realities: Beyond the Loop

“Threads are like tiny workers inside your program — when they cooperate well, your application becomes faster, smoother, and more responsive.”


What is Multithreading?
#

Imagine your program is a big task. Wouldn’t it be more efficient if multiple parts of it could run at the same time instead of waiting for one to finish before the next begins? That’s exactly what multithreading allows.

Multithreading is a technique where a single process can perform multiple tasks concurrently using threads. Think of threads as lightweight mini-programs that live inside a main program, sharing the same memory and resources.


Why Use Multithreading?
#

  • Faster Performance: Multiple tasks run in parallel, reducing total execution time.
  • Smarter Resource Use: Threads share the same memory space, avoiding the overhead of separate processes.
  • Better Responsiveness: Your app’s UI remains responsive even when doing heavy background work.

Threading vs Multiprocessing?
#

FeatureMultithreadingMultiprocessing
Memory UsageLow (shared memory)High (separate memory)
Suitable forI/O-bound tasksCPU-bound tasks
GILAffectedNot affected
ComplexitySimpleSlightly complex

How Does It All Work?
#

Each thread has:

  • Its own program counter (tells it what to do next)
  • Its own stack (for storing variables and function calls)
  • Access to the shared heap memory (common data area)

The system’s thread scheduler decides how and when threads run, sometimes switching between them rapidly, this is called context switching.


Where Do We Use Multithreading?
#

  • Games: Audio, rendering, physics, all handled by separate threads.
  • Web servers: Manage thousands of user requests at once.
  • Image editors: Apply filters to different image parts in parallel.
  • Downloaders: Download file segments simultaneously.

Writing Threads in Different Languages
#

Python
#

import threading

def task():
    print("Running in thread")

thread = threading.Thread(target=task)
thread.start()

What’s Happening Here?
#

  • threading.Thread() creates a thread object.

  • .start() begins execution in a new thread.

  • .join() tells the main program to wait until the thread is done.


Best Practices
#

  • Keep threads short-lived and task-specific
  • Use .join() to avoid premature exits
  • Avoid sharing mutable data unless protected
  • Consider threading.Lock() when using shared resources

What Makes Multithreading Hard?
#

Multithreading brings speed, but also complexity:

  • Race Conditions: Threads compete to access shared data, leading to unpredictable results.
  • Deadlocks: Two threads wait on each other forever.
  • Starvation: One thread never gets a turn.
  • Hard to Debug: Bugs can appear only in specific timings or conditions.

Tips for Writing Thread-Safe Code
#

  • Use mutexes/locks to protect shared resources.

  • Prefer immutable objects where possible.

  • Minimize shared state.

  • Use thread-safe libraries or higher-level concurrency tools like:

  • concurrent.futures (Python)

  • ExecutorService (Java)

  • std::async (C++) NOTE: I haven’t Explored this part though these are the possible solutions I found on Google.


Summary
#

Multithreading in Python is a powerful tool, especially when working with I/O-bound operations. While the GIL (Global Interpreter Lock) limits its use for CPU-intensive work, multithreading is still a go-to choice for network calls, UI responsiveness, and parallel I/O.

“Concurrency is not parallelism, but it’s a good place to start.” – Rob Pike