Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 5

Processes, Threads, and Context Switching

Recommended resources

In the last lesson, we traced the entire journey of an HTTPS request, from a DNS query all the way to the encrypted data exchange between a client and a server. That gave us a solid understanding of the network-level interactions. Now, let's shift our focus from the "what" and "how" of the connection to what happens inside the server when it receives that request.

Today's lesson will address a fundamental operating system concept that is critical for any backend developer: the distinction between processes and threads. Our goal is to differentiate between processes and threads and explain the concept of a context switch. A clear grasp of this topic is essential for understanding performance, concurrency, and scalability in backend systems, and it's a staple of technical interviews.

The Program and The Process

Let's start by clarifying some terminology. A program is a passive entity—it's a file on your disk containing a set of instructions, like a compiled Go binary or a Python script. It doesn't do anything on its own.

When you execute a program, the operating system loads it into memory, allocates resources for it, and begins running its instructions. At this point, the program becomes a process. A process is a program in execution; it's an active, living entity managed by the OS.

The ByteByteGo channel provides a great visual introduction to these concepts.

FANG Interview Question | Process vs Thread

Watch this short segment from the video "Process vs Thread".

Pay close attention to the explanation from the start to the end of the process section. The video clearly explains how a program becomes a process and highlights a key feature: process isolation.

As the video explains, each process runs in its own private, isolated memory address space. This is a crucial security and stability feature. The memory of one process cannot be directly accessed by another. If one process crashes (like a single tab in Google Chrome), it typically won't bring down other processes. This isolation, however, comes at a cost, which we'll explore shortly.


Introducing Threads: The Worker Within the Process

A process can be thought of as a container for execution. Within that container, the actual work is done by one or more threads. A thread is the smallest unit of execution that the OS can schedule to run on a CPU. Every process has at least one thread, known as the main thread.

The key distinction is that while processes are isolated from each other, threads within the same process share resources.

This diagram provides a clear picture of this relationship.

This diagram shows a single process containing three threads. Notice that resources like the executable code and environment variables are shared among all threads. However, each thread has its own unique identifier, stack, and registers—its private workspace.

Let's continue with the ByteByteGo video to see how it defines threads.

FANG Interview Question | Process vs Thread

Now, let's watch the next segment of the same video.

Watch the part that defines threads, from the beginning of the thread section until the discussion on context switching. Focus on what threads share and what is unique to each thread.

To summarize the relationship:

  • Shared Resources: All threads within a process share the same memory address space. This includes the executable code and the heap (where dynamically allocated data lives). This makes communication between threads very fast—they can simply read and write to the same memory locations.
  • Private Resources: Each thread has its own stack (for local variables and function calls) and its own set of CPU registers (including the program counter, which tracks the current instruction). This allows each thread to execute a different part of the code independently.

Comparing Processes and Threads

For a technical interview, you need to be able to articulate the differences clearly. Let's break them down point by point. The PrePaired article offers a concise, interview-centric way to frame this.

How to Answer: Explain the difference between a process and a thread | Flipkart Interview Question

This article is tailored for interview preparation and summarizes the key distinctions very effectively.

First, read the advice in the section How to Answer This Question. Then, review the Sample Answer to see how to package these points into a coherent response.

Here is a summary of the core trade-offs:

Feature Process Thread
Memory Each process has a completely separate memory address space. Threads within a process share the same memory address space.
Isolation High. A crash in one process does not affect others. Low. A crash in one thread can bring down the entire process.
Creation "Heavyweight". Creating a process is slow and resource-intensive. "Lightweight". Creating a thread is much faster and less resource-heavy.
Communication Complex and slower. Requires Inter-Process Communication (IPC) mechanisms like pipes or sockets. Simple and fast. Threads can communicate directly through shared memory.

One of the most important practical differences relates to blocking operations. This is a common follow-up question in interviews.

L-1.11: Process Vs Threads in Operating System

The video from Gate Smashers gives an excellent explanation of what happens when a process or thread gets blocked.

Watch the segment from the discussion on blocking. The key insight here is that since the OS often sees a multi-threaded application as a single process, a blocking system call in one thread can block all other threads in that process.

This distinction is fundamental. The independence of processes makes them robust, while the shared nature of threads makes them efficient for concurrent tasks within a single application, like a web server handling multiple requests.


The Juggler's Act: Context Switching

If you have a single CPU core, how can it run hundreds of processes and threads seemingly at the same time? The answer is that it doesn't. The OS creates the illusion of parallelism by rapidly switching the CPU's attention between different tasks. This act of saving the state of one task and loading the state of another is called a context switch.

This diagram shows the OS interrupting Process 1, saving its state into a data structure called a Process Control Block (PCB), and then loading the state of Process 2 from its PCB. The time spent doing this switching is pure overhead—no useful application work is being done.

The "context" that is saved includes:

  • CPU registers
  • The Program Counter (where the task left off)
  • The Stack Pointer
  • Information about the process's memory (its page table)

The OS scheduler decides which task runs next and for how long (its "time slice").


The Cost of a Switch: Processes vs. Threads

Context switching is not free. It consumes CPU cycles that could have been used for your application. Crucially, the cost of a context switch between two processes is significantly higher than between two threads of the same process.

Why? The primary reason relates to virtual memory management.

  • Process Switch: Since each process has its own isolated memory, switching from Process A to Process B requires the OS to tear down the memory mappings for A and set up the mappings for B. This involves invalidating the Translation Lookaside Buffer (TLB), a crucial hardware cache that speeds up memory access. A TLB "flush" is a very expensive operation.
  • Thread Switch: When switching between two threads in the same process, they share the same memory address space. The OS doesn't need to change the virtual memory mappings, and the TLB remains valid. It only needs to save and restore the thread-specific state (registers, stack pointer, etc.), which is much faster.

The following article provides an excellent deep dive into this, complete with a performance benchmark written in Go, which should resonate with your experience.

Context Switching Performance — Threads vs Processes

This article is perfect for understanding the performance implications of context switching. It details what happens under the hood and provides a practical demonstration.

Read from the beginning down to the first demonstration. Focus on the section that lists the three steps of a context switch: what actually happens. Pay special attention to step 2, "Flushing cache," as this is the key differentiator. Then, skim through the Go code examples and the performance results to see the real-world impact of the TLB flush when memory usage is high. The difference in sys time between the thread and process benchmarks highlights the overhead.


Conclusion

You should now have a solid framework for answering one of the most common OS-related interview questions. Let's recap the essentials.

Key Takeaways:

  • Process: A program in execution with its own isolated memory space. Provides robustness and security.
  • Thread: A lightweight unit of execution within a process. Threads share memory, enabling efficient communication and concurrency.
  • The Trade-off: Processes offer isolation at the cost of higher overhead for creation and communication. Threads offer efficiency at the cost of safety (one bad thread can crash the process).
  • Context Switch: The OS mechanism for juggling multiple tasks on a CPU by saving and restoring their state.
  • Performance: Context switching between threads is much cheaper than between processes, mainly because the shared memory address space avoids the costly invalidation of the memory management cache (TLB).

In our next lesson, we will build directly upon this foundation. Now that we know how an OS can run multiple threads concurrently, we'll investigate how modern backend servers leverage this to handle thousands of simultaneous client connections efficiently. We'll explore different I/O models, including blocking I/O, non-blocking I/O, and I/O multiplexing, which is the secret behind high-performance servers like Nginx and event-driven frameworks like Node.js.