Let's say I have a processor with 4 cores and 4 threads and an application with 20 threads that I need them to make constant checkings (let's say they are events), how does the processor run all threads at the same time with its limited amount of threads? I know that the processor changes between one thread an the other and, since the changes are so fast, we don't notice them, but is this all that happens or the computer does something else. Moreover, how does the computer save the information for each thread at a point on time, just in RAM memory?


2 Answers 2


20 threads cannot run at precisely the same time except on a system with 20 or more cores. What the system can do is make it look like they are running very close to being at the same time.

This is what the operating system scheduler is for.

Before the time of multi-core processors the operating system had to share CPU time across multiple processes, each of which had the potential to have multiple distinct threads.

The operating system has to manage each thread, allocating it an amount of time on the CPU, restoring state, running the thread, suspending and saving state. None of this is massively different between multi-core, multi-CPU or single-core.

What has changed is the level of complexity and the number of things that can be scheduled to run at the same time. Where we could only run one thread at a time we can now run four. The same process of keeping track of thread state happens (program counter, etc) and it doesn't matter how many threads a program has.

The operating system will try to fairly schedule all of the threads some time on the CPU based on whether they have work to do (might be waiting on a hardware interrupt or some data from disk), what the priority of the process/thread is and a whole raft of other things. Threads can notify the operating system that they have no work to do until various events occur and that can be down to time, hardware or software events and so on. In that case the operating system scheduler can simply skip over that thread until it finds a thread ready to do some work.

At the moment the system I am using is reporting that there are 2500 threads across all the processes running, obviously it would be impossible for them all to be running simultaneously on a 4 core processor.


First: A CPU does not "have" threads, despite what the marketing cruft tries to claim. A CPU can run up to the indicated number of threads at one time. Specifically, a CPU with n cores and hyperthreading not enabled can run n threads. A CPU with n cores and hyperthreading enabled can run 2_n_ threads. In technical contexts we refer to "the thing that can run a thread" as a logical processor, or LP. A machine without HT enabled has one LP per core; HT gives it two.

A typical Windows system has large hundreds or even small thousands of threads, total, in it at one time. This is up to each individual program's code to decide. When you create a process, that process always starts out with one thread. Some simple programs, particularly command-line (character mode) programs, may use only one thread. But the code running in that first thread can create other threads, and those threads can create other threads, and so on, almost without a practical limit. There are good reasons to not simply create a huge number of threads, but there is nothing that would make it impossible to create far more threads than one would have a use for.

(On x86, with the default values for thread stack size, there is a limit at about 2000 threads per process - imposed by the address space limit.)

In Task Manager's Details tab, you can enable the Threads column, which will tell you how many threads are in each process at the moment. Here is a PowerShell command that will count up all of the threads in your system:

($threads = get-ciminstance win32_thread).count

This is on a machine with four hyperthreaded cores, total of eight LPs.

This is not a problem because only a very few of those threads actually want to run at any moment. Most threads in most processes spent most of their time in what Windows calls a "wait" state, meaning they don't want to, or can't, use CPU time at all at the moment. They're waiting for I/O (maybe network, maybe disk, etc.) to complete, they're waiting for user input, they're waiting for some other thread to release a resource that they need to access, etc. (*nix-derived systems call this "blocked".)

If you want the number of threads that are Waiting, try this:

PS C:\Users\jeh> ($threads = get-ciminstance win32_thread | where-object -Property ThreadState -EQ 5).count

So it looks like there are only 10 threads trying to use the LPs at the moment. But it's even better than that. With 8 LPs, 8 of those threads are the system's idle threads. There's an idle thread dedicated to each LP. They're always ready to run, but they only run if nothing else wants the LP. So at the moment I did the commands above there were only two "real" threads that wanted to do work. The idle threads' activities are not included in Task Manager's line graph displays of CPU utilization.

n.b.: These numbers aren't quite accurate because these Powershell and WMI operations are not internally synchronized with the OS's functions. But they're easily close enough to illustrate the point.

If there are more threads (other than the idle threads) "Ready" than there LPs, then the scheduler, in general, picks the highest priority nLPs threads - subject to some tweaks according to who ran on what CPUs recently. If there are multiple threads at the same priority they may be "time-sliced", running in a "round-robin" fashion, each one getting to run for 20 or 60 msec before the scheduler makes the LP switch to another.

Here is an answer I gave that goes into much more detail about how thread priorities work in Windows.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .