notesonly.in

One notebook for every subject — open it anywhere.

Log in

Multithreading Basics: Complete Beginner's Guide Guide.

A thread is the smallest unit of work an operating system can schedule on the CPU. A running program, called a process, can contain many threads. All threads inside one process share the program's memory and resources, but each keeps its own private stack, registers, and program counter. Multithreading splits a program into such threads so its parts can progress at the same time instead of one after another.

This matters because modern machines have multiple CPU cores and users expect responsive apps. A video player must keep playing while downloading the next chunk; a web server must answer hundreds of browsers at once. Without threads, one slow task such as waiting for a file would freeze everything. Multithreading overlaps waiting time with useful work and spreads computation across cores.

Key Concepts

  • Process: a running program with private memory; one process can host many threads.
  • Thread: a lightweight execution path; shares memory but has its own stack and registers.
  • Concurrency vs parallelism: concurrency is tasks interleaving on one core; parallelism is tasks truly simultaneous on multiple cores.
  • Context switch: the OS pausing one thread and resuming another; each switch costs time.
  • Race condition: two threads reading and writing shared data in an unlucky order, producing a wrong result.
  • Deadlock: two threads each waiting forever for a lock the other holds; the program freezes.
  • Mutex (lock): only the thread holding the lock may touch shared data, so updates happen one at a time.
  • GIL: in CPython only one thread runs Python bytecode at a time — threads help I/O-bound, not CPU-bound, programs.

How It Works

  1. The program is divided into independent tasks, like downloading file A and file B.
  2. One thread is created per task (or tasks go to a thread pool); all threads share the program's memory.
  3. The OS scheduler gives each thread time slices on CPU cores, switching thousands of times per second.
  4. When a thread blocks waiting for data, the scheduler instantly runs another ready thread.
  5. Threads coordinate through locks or queues to keep shared data consistent; results combine at the end.

Worked Example

You must download 4 files of 50 MB each at 10 MB/s. Time per file = 50 divided by 10 = 5 seconds, so sequential download takes 4 times 5 = 20 seconds. With 4 threads, all downloads run at once: while one thread waits for network data, the others keep receiving. Total ≈ 5 seconds plus 0.2 s of thread-creation overhead = 5.2 s. Speedup = 20 divided by 5.2, about 3.85. Threads did not make the internet faster; they overlapped the waiting. Pure calculation on one core still takes about 20 seconds — the GIL serializes it anyway.

Common Misconceptions

  • More threads always means more speed. Beyond a point, context-switching overhead dominates; match thread count to cores for compute work, and use more threads only for I/O waiting.
  • Threads always run simultaneously. Only on multiple cores; on one core they take turns too fast to notice.
  • Multithreading removes all waiting. It overlaps work with waiting; CPU-bound Python gains nothing from threads — use multiprocessing instead.

Real-World Applications

  • Web servers: hundreds of simultaneous requests, roughly one thread per connection.
  • Browsers: UI thread separate from the page-loading thread, so scrolling never freezes.
  • Games: one thread renders graphics while another runs physics and AI.
  • Desktop apps: a background thread saves your file while you keep typing.

Multithreading lets one program do several things at once: threads share memory, the OS schedules them across cores, and locks keep shared data safe. Master threads versus processes, race conditions, and deadlocks, and your programs stay fast and responsive.