Funify Posts

IT-Concepts

What Is Context Switching? How Does a CPU Seem to Handle Multiple Tasks at Once?

Thumbnail image for What is context switching

Today, I'd like to take a closer look at Context Switching, a concept that comes up frequently when studying operating systems.

When we use a computer, we can browse the web, listen to music, download files, and chat with someone at the same time. Because all of these programs appear to be running simultaneously, it is easy to assume that the CPU is processing all of them at exactly the same moment.

Modern CPUs do have multiple cores, so several tasks can genuinely run in parallel. However, if we look at a single CPU core, it can essentially execute only one task at any given instant.

So how does it appear as though many programs are running at the same time?

One of the key reasons is that the CPU switches between different tasks extremely quickly.

This is where Context Switching comes in.


What Is Context Switching?

Context Switching is the process of saving the execution state of the currently running process or thread, loading the saved state of another one, and then switching the CPU to that task.

Let's look at a simple example.

Suppose the CPU is currently executing a process called P1.

After running P1 for a while, the operating system may decide that it is time to run P2 instead.

The CPU cannot simply stop P1 and forget about it. When P1 gets CPU time again later, it needs to continue from exactly where it left off.

So the system first saves the current state of P1.

The operating system's scheduler then selects the next task to run, restores the previously saved state of P2, and allows the CPU to continue executing P2.

The overall flow looks like this:

P1 Running → Save P1 Context → Scheduler Selects Next Task → Restore P2 Context → P2 Running

This entire process is known as Context Switching.

The word context refers to the information the CPU needs in order to resume a task later from the point where it was interrupted.


What Information Is Saved?

While a program is running, many pieces of information inside the CPU are constantly changing.

One of the most important is the Program Counter (PC).

The Program Counter stores the address of the next instruction the CPU should execute.

CPU registers contain values currently being used for calculations, while the Stack Pointer indicates the current position of the stack. The processor also maintains status flags and other information related to execution and scheduling.

Typical context information includes:

Program Counter, CPU Registers, Stack Pointer, Processor Status, and Scheduling Information

The operating system manages process-related information through structures such as the PCB, or Process Control Block, while threads also maintain their own execution states.

The important point is not to memorize every internal structure.

What matters is understanding that the operating system saves enough information so that the CPU can later resume the task exactly where it stopped.

You can think of it like working on a document, switching to another task for a while, and then returning to continue from the exact point where you left off instead of starting over.


When Does Context Switching Occur?

One common case is when a Time Quantum expires.

In many scheduling algorithms, the operating system prevents one process from monopolizing the CPU by allowing it to run only for a limited amount of time.

For example, in Round Robin Scheduling, each process is given a fixed amount of CPU time.

If the Time Quantum is 5 ms, execution might look like this:

P1 5 ms → P2 5 ms → P3 5 ms → P1 again

When P1's time slice expires, the operating system saves P1's state and restores P2's state.

A Context Switch occurs between those two tasks.

I/O is another common reason for a switch.

Suppose P1 is running and requests an I/O operation such as disk access or network communication.

I/O operations are often much slower than CPU instructions, so it would be inefficient for the CPU to sit idle waiting for the operation to finish.

Instead, the operating system can move P1 into a Waiting state and allow another process in the Ready state, such as P2, to run.

The sequence may look like this:

P1 Running → I/O Request → P1 Waiting → Context Switch → P2 Running

This is closely related to the concept of Blocking I/O.


Are More Context Switches Better?

This is an important point.

Context Switching is essential for multitasking, but the switching itself does not perform useful application work.

While the CPU is saving P1's registers and restoring P2's state, it is not processing the actual workload requested by the application.

That means Context Switching introduces a certain amount of overhead.

Let's look at a simple example.

If P1, P2, and P3 have relatively long Time Quantums, the execution timeline may look something like this:

P1 ─────── CS ─ P2 ─────── CS ─ P3

Now imagine that the Time Quantum is extremely short:

P1 ─ CS ─ P2 ─ CS ─ P3 ─ CS ─ P1 ─ CS ─ P2 ─ CS ...

The CPU now spends much more time switching between processes.

If too much CPU time is spent changing tasks rather than executing them, overall efficiency can decrease.

So a higher number of Context Switches does not necessarily mean better multitasking performance.


Saving Registers Is Only Part of the Cost

It is easy to think that Context Switching simply means saving a few registers and loading another set.

In practice, the performance impact can be more complicated.

Modern CPUs rely heavily on cache memory.

Frequently used data is stored in the CPU cache so that it can be accessed much faster than data in main memory.

When the CPU switches from one process or thread to another, some of the data already loaded into the cache may no longer be useful to the new task.

This can reduce cache locality and increase the number of cache misses.

A process switch may also involve changes to the memory address space, which can affect structures such as the TLB, or Translation Lookaside Buffer.

Because of this, the actual cost of Context Switching depends on many factors, including:

  • CPU architecture
  • Operating system
  • Current workload
  • Cache state
  • Memory mapping
  • Number of runnable tasks

This is why it is difficult to say that every Context Switch always takes a specific number of microseconds or milliseconds.


Are Process and Thread Context Switches the Same?

Both processes and threads can undergo Context Switching, but the cost is not always the same.

Different processes generally use separate address spaces.

When the CPU switches from Process A to Process B, the memory mapping may also need to change.

Threads within the same process, on the other hand, typically share the same code, heap, and address space.

Each thread still has its own execution state, including registers and a stack, so switching between threads still requires a Context Switch.

However, switching between threads within the same process is generally less expensive than switching between completely separate processes.

That does not mean thread switching is free.

If an application creates too many threads, the scheduler has more runnable threads to manage, which can lead to more frequent Context Switching.

This is one reason why simply creating more threads does not automatically improve server performance.


What Happens When Blocking I/O and Thread Counts Increase?

Consider a web server receiving many requests at the same time.

Suppose the server uses one thread per request and each thread performs Blocking I/O.

Thread A may be waiting for a database response.

Thread B may be waiting for file I/O.

Thread C may be waiting for a network response.

As the number of requests increases, the number of threads can also grow significantly.

Each thread requires memory for its stack and other state, and the operating system scheduler has more threads to manage.

As a result, Context Switching overhead may also increase.

This is one reason high-concurrency systems often use techniques such as:

Thread Pools, Non-Blocking I/O, I/O Multiplexing, and Event Loops

On Linux, mechanisms such as select, poll, and epoll allow applications to manage many I/O connections without necessarily creating one thread for every connection.

So Context Switching is not just an isolated operating-system concept.

It is closely connected to topics such as Blocking I/O, Non-Blocking I/O, Thread Pools, and Event-Driven Architecture.


Does Every System Call Cause a Context Switch?

There is another important distinction to understand.

A System Call or Interrupt does not always cause a Context Switch.

Suppose Process A makes a system call.

The CPU may switch from User Mode to Kernel Mode:

Process A User Mode → Process A Kernel Mode → Process A User Mode

The CPU's privilege mode changes, but the same process is still running.

This is a Mode Switch, not necessarily a Context Switch.

A Context Switch occurs when the CPU actually changes from one schedulable task to another.

For example:

Process A Running → Save A Context → Scheduler → Restore B Context → Process B Running

So Mode Switches and Context Switches should not be treated as the same thing.


Context Switching in Practice

Context Switching can feel fairly abstract when it is explained only in text.

It becomes easier to understand when you can see how processes move between the Ready, Running, and Waiting states and how CPU execution changes over time.

I created a simple Context Switching Simulator that shows the CPU, Ready Queue, Waiting Queue, and CPU Timeline.

You can change values such as:

  • Process Count
  • Time Quantum
  • Context Switch Cost
  • I/O Frequency

and then observe how they affect CPU scheduling, the number of Context Switches, and CPU efficiency.

One particularly useful experiment is to compare a large Time Quantum with a very small one.

As the Time Quantum becomes shorter, the CPU switches between processes more frequently, which increases the number of Context Switches.

The CPU Timeline also separates actual process execution from Context Switching overhead.

For example:

P1 → CS → P2 → CS → P3 → CS → P1

Here, CS represents the time spent performing a Context Switch.

By changing the Time Quantum or Context Switch Cost, you can compare how Useful CPU Work, Context Switch Time, and CPU Efficiency change.


Final Thoughts

Context Switching is the process of saving the state of the currently running process or thread, loading the state of another task, and transferring CPU execution to that task.

It is one of the key mechanisms that makes multitasking possible, but Context Switching itself also has a cost.

If there are too many processes or threads, or if the Time Quantum is set too short, the CPU may spend a significant amount of time switching between tasks rather than doing useful work.

The goal, therefore, is not to eliminate Context Switching.

It is to maintain the required level of concurrency and responsiveness while avoiding unnecessary switching overhead.

Once you understand Context Switching, concepts such as CPU Scheduling, Threads, Blocking and Non-Blocking I/O, Thread Pools, and Event Loops also become much easier to connect.


Context Switching Simulator

If you want to see how Context Switching behaves under different conditions, you can try the simulator below.

The page lets you change the number of processes, Time Quantum, Context Switch Cost, and I/O Frequency while observing CPU scheduling behavior, Context Switch counts, and CPU efficiency.

Comparing a larger Time Quantum with a smaller one is especially useful because it clearly shows how frequent switching can reduce the amount of time the CPU spends doing actual work.

Context Switching Simulator

Thanks for reading. I hope you found it helpful!

#ContextSwitching #OperatingSystem #Process #Thread #CPUScheduling #TimeQuantum #BlockingIO #NonBlockingIO #ThreadPool #IOProcess #ComputerScience #OperatingSystems

This article is also available in Korean: Read the Korean version