Technology

What Is a Process or Thread, and How Does Your Computer Run So Many Things at Once?

Or: why Spotify, Chrome, Discord, Windows, and your game can all seem to run at the same time. Existing at once and executing at once are not the same thing.

Or: Why Spotify, Chrome, Discord, Windows, and Your Game Can All Seem to Run at the Same Time

Open Task Manager on a typical computer and the number of things apparently running can be startling. A browser with twenty tabs, music playing in the background, a chat app waiting for messages, cloud storage syncing files, and dozens of Windows services you never manually started — add a game or a video editor on top of all that, and the computer can still feel perfectly responsive. At first glance that seems impossible. A processor executes instructions so quickly, but even a modern CPU has a limited number of physical cores, while the operating system may show hundreds of processes and thousands of threads apparently existing at the same time.

The trick is that existing at the same time and executing at the exact same instant are not the same thing. Modern computers create the illusion of enormous simultaneous activity by dividing programs into processes and threads, spreading work across multiple CPU cores, and rapidly switching among tasks that need attention — a system the operating system coordinates through scheduling. Understanding it explains a surprising amount about how computers behave, including why one frozen application usually doesn't freeze everything else, and why adding CPU cores helps some workloads far more than others.

A Program and a Process Aren't Quite the Same Thing

People often use "program" and "process" interchangeably, but they describe different things. A program is stored instructions and data sitting on a drive — Microsoft Word exists as software even when nobody's using it. Launch Word, and the operating system creates a process: the running instance of that program, with its own memory, security permissions, and an environment where its code can actually execute. Microsoft's own documentation on Windows processes and threads puts it plainly — a process provides the resources a running program needs, including a virtual address space, open handles, a security context, and at least one thread of execution. Think of the program as a recipe in a cookbook and the process as someone actually cooking it: the recipe itself isn't preparing anything. This becomes obvious the moment you open two copies of the same application — the executable file on disk hasn't multiplied, but the system happily creates two separate processes from it.

One of the operating system's most important jobs is keeping those processes separated. Each one typically gets its own private virtual address space, so a bug in a music player can't simply overwrite part of a browser, and malware has a much harder time reaching into another program's memory. Modern operating systems enforce that separation with hardware-supported memory protection — a program generally cannot reach into another process's memory unless the system deliberately allows some narrow, controlled form of sharing. That isolation is a large part of why modern systems are so much more stable than older ones: a badly behaved application can still crash, but the damage is usually contained inside its own process rather than taking the whole machine down.

One Process Can Still Have a Lot to Do

A single process can still involve plenty of simultaneous-feeling work. A web browser has to respond to your mouse and keyboard, render the interface, load files, communicate across the network, run scripts, decode images, and keep several pages going at once — doing all of that as one perfectly sequential stream of instructions would mean the browser freezing the moment it started downloading something. This is where threads come in: Microsoft's documentation defines a thread as the entity within a process that the operating system can actually schedule for execution, with every thread in a process sharing that process's memory and resources. A process is the restaurant — one building, one kitchen, one set of records — and threads are the workers inside it, taking orders, cooking, and washing dishes while sharing the same space. Sharing memory makes communication between threads efficient, but it also means one thread can interfere with data another thread is using if the software doesn't coordinate carefully — a tension that becomes important later.

A process starts with at least one thread, often called the main thread, and can create more as needed; a modern game, for instance, might run separate threads for rendering preparation, physics, audio, asset loading, and AI. That doesn't mean all of those threads are actively using the CPU at every moment — most spend a surprising amount of time simply waiting. A browser waits for data from a server. A media player waits for the next chunk of audio to be needed. A messaging app spends most of its life waiting for a message to arrive. While a thread is waiting, it doesn't need to occupy a CPU core, and the operating system can let something else run instead — a big part of why a computer can comfortably support far more threads than it has cores.

The Scheduler Decides Who Gets a Turn

At the center of all this is the CPU scheduler, which decides which runnable thread gets processor time, on which core, and for roughly how long — threads merely waiting for something generally aren't competing for that time at all until whatever they're waiting for becomes available. On a single CPU core, the processor might run thread A briefly, switch to B, then C, then back to A, and if those switches happen quickly enough, all of them appear to be progressing simultaneously. This is time slicing, or preemptive multitasking: a thread gets a slice of CPU time, and the operating system can interrupt it so another thread gets a turn, rather than letting whichever program started first simply hog the processor. To a human watching the screen, these tiny slices blend into continuous activity — music keeps playing while a browser loads a page because the processor is switching between them far faster than anyone can perceive.

The hand-off between threads is called a context switch. The CPU has to save the outgoing thread's state — registers, instruction position, stack information — so it can resume later exactly where it left off, then load the incoming thread's saved state and continue, much like inserting a bookmark every time you switch between several books at once. Modern processors do this remarkably quickly, but it still isn't free: saving and restoring state and juggling caches all cost something, so scheduling is a constant balancing act between staying responsive and giving each thread enough uninterrupted time to actually accomplish something.

Multiple Cores Add Real Parallelism — With Limits

Time slicing explains how one core can make many tasks feel simultaneous, but modern computers also have several physical cores, which changes the picture: an eight-core processor can genuinely execute instructions from several threads at the exact same moment, a property called parallelism, distinct from multitasking's rapid switching on a single core. Even an eight-core machine typically has far more runnable threads than cores over time, so scheduling and context switching remain essential regardless. But extra cores only help if a program's work can actually be split into pieces that run independently — a long calculation where every step depends on the one before it doesn't parallelize no matter how many cores you throw at it, while thousands of genuinely independent tasks divide up easily.

Wikipedia's entry on Amdahl's Law captures exactly why this ceiling exists: the speedup available from parallelizing a program is limited by whatever portion of it must still run sequentially. If ten percent of a workload can't be split up, even infinitely fast parallel hardware for the remaining ninety percent still leaves that sequential ten percent in place, which is why doubling a processor's core count doesn't come close to doubling most applications' real-world performance. Video encoding and scientific computation tend to parallelize well; a game or everyday application often runs into the limits of one or two critical threads long before it runs out of cores to use. This is also why a sixteen-core CPU can show only 30 percent total utilization while still being the exact bottleneck holding a game back — one heavily loaded thread can max out a single core while fifteen others sit comparatively idle, and the game still can't produce frames any faster because that one thread has no performance left to give.

Shared Memory Is Powerful, and Dangerous

Because threads inside a process typically share memory, cooperation between them is fast — one thread can download data while another processes it, communicating through shared structures instead of copying everything back and forth. But that convenience creates a real hazard: a race condition, where the outcome of a program depends on the unpredictable timing of concurrent operations in a way nobody intended. The standard systems-programming textbook Operating Systems: Three Easy Pieces walks through exactly this kind of bug in its chapter on common concurrency problems — two threads reading and modifying the same shared value at nearly the same moment can silently lose one of the updates, with neither thread doing anything individually unreasonable. The bug exists purely because the access wasn't coordinated.

Locks — mutexes, semaphores, and related mechanisms — exist to prevent exactly this, letting software say "only one thread may touch this at a time." But locks introduce their own failure mode. Three Easy Pieces lays out the textbook deadlock scenario directly: thread A holds one resource and needs a second; thread B holds that second resource and needs the first. Neither can proceed, and from the outside the application looks completely frozen — Task Manager may show it using essentially no CPU at all, because the problem isn't that it's overwhelmed with calculations, it's that it's waiting for something that will never happen. This is also why "Not Responding" doesn't automatically mean a program has crashed: if the interface thread is blocked on a lock, a disk operation, or a network request, the rest of the program may still be intact and capable of recovering the moment that blocking operation resolves.

Why One Frozen App Usually Doesn't Freeze Everything

Process isolation is the reason a runaway photo editor doesn't take the whole system with it. If one process enters an infinite loop, the scheduler can still allocate time to everything else — your mouse keeps moving, music keeps playing — because the bad process doesn't own the machine, and memory protection prevents it from writing into the operating system or other programs. That isolation doesn't mean processes can never cooperate: operating systems provide inter-process communication through pipes, sockets, and shared memory, so applications can exchange information deliberately rather than by one simply reaching into another's private memory.

Chromium's own design documentation on its multi-process architecture is a good illustration of why this separation is worth the overhead it costs. Rather than running an entire browser inside one process — where a single bad web page could take the whole thing down — Chromium splits work across a main browser process and separate renderer processes, so a crash or exploited vulnerability in one page's content stays contained. That's also a security boundary: a process rendering an untrusted page from the open internet doesn't need unrestricted access to the rest of the computer, so isolating it into its own sandboxed process lets the browser grant it only what it needs. A long list of Chrome processes in Task Manager isn't automatically evidence of bloat — a fair amount of it is the security architecture working as intended.

This is also why process and thread counts are a poor proxy for how hard a computer is working. Two hundred processes can sit almost entirely idle if most are simply waiting for network events or user input, while a single misbehaving process can consume an entire core by itself. CPU-usage percentages represent processor time actually consumed, not how "hard" a program exists: an application can stay open for ten hours while barely touching the CPU, while another saturates every core for thirty seconds and goes quiet. Phones push this further still, because battery life depends on it — mobile operating systems aggressively suspend background apps and batch small jobs together so the CPU doesn't keep waking for tiny tasks, which is why force-closing every app isn't really the battery-saving habit people assume it is.

The Bard's Take

A modern computer doesn't run hundreds of programs by giving each one its own private CPU. It organizes software into processes, which provide isolated environments with their own memory and resources, and inside those processes run threads, the actual paths of execution doing the work. Most of those threads aren't competing for the processor at any given instant — plenty are simply asleep, waiting for a network reply, a timer, or a click — and when several genuinely are ready at once, the scheduler decides who goes next. On a single core, that happens through rapid switching convincing enough that simultaneous activity is really an illusion; on a machine with several cores, some of it is genuinely happening at once, though there are still usually more runnable threads than there are cores to run them on.

That's the whole explanation hiding behind an ordinary afternoon at the computer: why music keeps playing while a browser loads a page and an update downloads in the background, why one crashed tab doesn't take out the whole browser, and why a sixteen-core processor can still bottleneck on a single demanding thread while the rest of the system reports looking comparatively idle. Task Manager was never showing you hundreds of programs locked in a fight over the processor. It's showing a pool of potential participants in an extraordinarily fast scheduling system — most of them waiting patiently for their turn, which, as far as your own senses are concerned, never seems to come late enough to notice.

Sources