Threads and Multithreading
# CHAPTER 6
Threads and Multithreading
1. Introduction
When you open Microsoft Word, you are launching a Process. As you type a document, Word is simultaneously checking your spelling in the background, auto-saving your work to the hard drive every 60 seconds, and accepting new keystrokes. If a Process can only execute one line of code at a time on the CPU, how can Word do three things at once? The answer is Threads. A thread is a "lightweight process." Instead of launching three massive, memory-heavy processes to handle spelling, saving, and typing, the OS allows a single process to spawn multiple independent threads that share the same memory space. In this chapter, we will master the architecture of Threads, contrast them against heavy processes, and explore the immense performance benefits of Concurrency and Multithreading.2. Learning Objectives
By the end of this chapter, you will be able to:- Define a Thread and explain its relationship to a Process.
- Differentiate between the heavy overhead of Processes and the efficiency of Threads.
- Explain the concept of shared memory space (Code, Data, Heap) among threads.
- Understand the difference between User-Level Threads and Kernel-Level Threads.
- Define Concurrency vs. Parallelism in multi-core CPU environments.
3. What is a Thread?
A Thread is the smallest unit of execution that can be scheduled by an Operating System. A Process is the heavy container; it holds the memory, the files, and the permissions. A Thread is the actual "worker" inside the container executing the code.- Single-threaded Process: Has exactly one worker. It can only do one task at a time.
- Multithreaded Process: Has many workers inside the same container. They can all work on different tasks simultaneously.
4. Threads vs. Processes
Why use threads instead of just creating multiple processes? 1. Memory Sharing: If you launch two separate Processes, the OS builds a massive, thick concrete wall between them for security. Process A cannot see Process B's memory. If they need to talk, it requires complex, slow Inter-Process Communication (IPC). If you launch two Threads *inside the same Process*, there is no wall! Thread 1 and Thread 2 share the exact same Data and Heap memory. Thread 1 can change a variable, and Thread 2 instantly sees the change.2. Context Switching Speed: Switching the CPU from Process A to Process B is exhausting for the OS. It has to flush the memory caches and load a massive PCB. Switching the CPU from Thread 1 to Thread 2 (within the same process) is incredibly fast because they already share the same memory space. The OS only has to swap the tiny Thread Control Block (TCB).
5. User Threads vs. Kernel Threads
Threads exist on two different architectural levels:- User-Level Threads: Managed entirely by a software library (like Java Threads) in User Space. The Kernel doesn't even know they exist. The Kernel thinks there is only 1 heavy process running. (Fast to create, but if one User Thread crashes or waits for a hard drive, the Kernel blocks the *entire* process, stopping all other threads!).
- Kernel-Level Threads: Managed directly by the Operating System Kernel (like Windows Threads). The Kernel is fully aware of all of them. (Slower to create, but if one thread waits for the hard drive, the Kernel happily lets the other threads keep running).
6. Concurrency vs. Parallelism
These terms are often confused:- Concurrency (The Illusion): You have a Single-Core CPU. Thread A runs for 10ms, then Thread B runs for 10ms. They are taking turns so fast it *looks* like they are running at the same time, but mathematically, they are not.
- Parallelism (The Reality): You have a Multi-Core CPU (e.g., 4 cores). Thread A is physically running on Core 1, and Thread B is physically running on Core 2 at the exact same nanosecond.
7. Diagrams/Visual Suggestions
*Visual Concept: Process vs. Threads Memory Model* Draw two large boxes. Box 1 (Single Process, 2 Threads): Draw a large container labeledProcess 1. Inside it, draw one massive pool of Code, Data, and Heap. Draw two small workers (Thread 1 and Thread 2). Both workers have their hands in the exact same Data pool.
Box 2 (Two Processes): Draw two completely separate heavy containers (Process 1 and Process 2). Each has its own private, isolated Code/Data/Heap pool. Draw a thick brick wall between them.
This visualizes why multithreading is incredibly memory efficient compared to multiprogramming.
8. Best Practices
- Beware of Shared Data: Multithreading is powerful but extremely dangerous. Because all threads share the same Data memory, what happens if Thread 1 tries to change an account balance to $50 at the *exact same microsecond* Thread 2 tries to change it to $100? The data becomes corrupted. Software developers must use "Locks" (Synchronization) to prevent threads from colliding. (We will cover this deeply in Chapter 8).
9. Common Mistakes
- Assuming More Threads = More Speed: A junior developer thinks, "If 4 threads make my program fast, 4,000 threads will make it 1,000x faster!" This is false. Every thread requires a tiny slice of CPU time to perform a Context Switch. If you create 4,000 threads, the CPU will spend 99% of its time switching between them, and only 1% of its time actually running the code. This is called "Thrashing."
10. Mini Project: Observe Thread Counts
Let's see how heavily modern software relies on threads. Windows:- 1. Open Task Manager. Click the Details tab.
- 2. Right-click the column headers (Name, PID) and click Select Columns.
- 3. Check the box for Threads and click OK.
- 4. Look at Google Chrome or a modern Video Game. You will likely see one single Process utilizing 40 to 100 individual Threads!
top -H in the terminal to view individual threads instead of just processes.
11. Practice Exercises
- 1. Explain the specific memory components that are *shared* among all threads within a process, versus the memory components that are *private* to each individual thread (Hint: The Stack).
- 2. Differentiate between Concurrency and Parallelism in a multi-core CPU architecture.
12. MCQs with Answers
An application needs to perform three tasks simultaneously. The developer can architect the software as three distinct Processes, or as one Process with three Threads. Why is the Multithreading approach significantly more efficient for the Operating System?
Which thread architecture allows the Operating System Kernel to be fully aware of the threads, ensuring that if one thread is blocked waiting for Hard Drive I/O, the Kernel can smoothly continue executing the other threads in the process?
13. Interview Questions
- Q: A web server needs to handle 1,000 simultaneous user connections. Explain the architectural difference between spawning 1,000 independent Processes versus spawning 1,000 Threads within a single Process. Focus on RAM consumption.
- Q: In a multithreaded process, Thread A and Thread B share the same Code, Data, and Heap. However, they do not share the exact same "Stack". Why must every thread possess its own private Stack? *(Hint: Tracking function calls and local variables).*
- Q: Explain the difference between Concurrency and Parallelism. Can a system achieve Concurrency on a physical CPU that only possesses a single processing core?