Objective

See real threads on your own PC: how many each program has, what state they are in, how busy the scheduler is, and what a thread's stack looks like. You only look. Nothing here changes any setting (the optional priority step in Part 5 is undone when the program closes).

Time: 25–30 minutes
You need: A Windows 10 or 11 PC. Parts 1–4 need nothing extra. Part 6 uses one free Microsoft tool, Process Explorer.

What to Open

ToolHow to open it
Task ManagerPress Ctrl + Shift + Esc, then click More details if it looks small
PowerShellPress Win, type PowerShell, press Enter (normal, not admin)
Performance MonitorPress Win + R, type perfmon, press Enter
Resource MonitorPress Win + R, type resmon, press Enter

Part 1: Count Threads in Task Manager

1A. The whole PC. In Task Manager open the Performance tab and click CPU. Under the graph, find Processes, Threads and Handles.

  1. Processes: ________________
  2. Threads: ________________
  3. Logical processors (bottom right): ________________
  4. Threads ÷ Processes (about): ________________

1B. Per program. Open the Details tab. Right-click any column header, choose Select columns, tick Threads, and click OK. Click the Threads header to sort.

  1. Which process has the most threads? ________________ How many? ________________
  2. How many threads does explorer.exe have? ________________
  3. How many threads does a tiny program like Notepad have? (Open it if needed.) ________________

Windows 11 Task Manager (the new design) has the same Details tab. If your Task Manager has a left-hand menu, click the Details icon.

Part 2: Ask PowerShell (Same Facts, Another Way)

# the 10 processes with the most threads
Get-Process | Select-Object Name, Id, @{n='Threads';e={$_.Threads.Count}} |
    Sort-Object Threads -Descending | Select-Object -First 10
 
# total number of threads in the whole system
(Get-Process | ForEach-Object { $_.Threads.Count } | Measure-Object -Sum).Sum
  1. Does the top process match the one you found in Part 1B? ________________
  2. Total thread count: ________________ (it may differ slightly from Task Manager, as threads come and go)

Now look inside one process. Replace explorer with any program that is running:

(Get-Process -Name explorer).Threads |
    Select-Object -First 15 Id, ThreadState, WaitReason, BasePriority, CurrentPriority,
                  StartTime
  1. How many of those threads are in the Running state? ________________
  2. What is the most common ThreadState (usually Wait)? ________________
  3. What WaitReason shows up most? ________________
  4. What is the BasePriority of these threads? (It is usually 8 for a Normal-class process.) ________________

(Do the same for notepad. You will see most of its few threads waiting.)

Part 3: Watch the Scheduler in Performance Monitor

Open perfmon, click Performance Monitor in the left tree. Click the green + button. Add these counters:

CounterWhere
\System\Context Switches/secSystem
\System\Processor Queue LengthSystem
\System\ThreadsSystem
\Processor(_Total)\% Privileged TimeProcessor

Watch the graph for about a minute while you do nothing. Then open a few web pages or drag a window around.

  1. Context switches per second while idle: ________________ and while busy: ________________
  2. Processor Queue Length (usually 0 to 2 on a quiet PC): ________________

Processor Queue Length counts threads in the Ready state (Section 4). A queue that stays above about 2 for each logical processor suggests the CPU is overloaded.

Part 4: Wait Chain in Resource Monitor

Open resmon, click the CPU tab. In the Processes list, tick the box next to any running program. At the bottom, the Associated Handles panel shows everything that program has open (files, events, mutexes, threads).

  1. In Associated Handles, type Mutant in the search box. (Windows calls a mutex a "Mutant" internally.) Do you see any? ________________

Now right-click a program name in the list and choose Analyze Wait Chain. A healthy program shows a short chain, or nothing. If a program is hung because of a deadlock, the window would say it is waiting for another thread, and it may report that the process is deadlocked.

  1. What did Analyze Wait Chain report for your program? ________________

Part 5 (Optional): Priority Experiment

  1. Open Notepad and the Details tab in Task Manager.
  2. Right-click notepad.exe → Set priority. Note its current class (usually Normal).
  3. Run this in PowerShell and watch BasePriority change:
$p = Get-Process notepad
$p.PriorityClass                      # Normal
$p.PriorityClass = 'High'             # raise it (never choose Realtime)
(Get-Process notepad).Threads | Select-Object -First 3 Id, BasePriority
$p.PriorityClass = 'Normal'           # put it back
  1. What was BasePriority at Normal? ________________ At High? ________________ (Expected: about 8 and 13.)

Part 6: Process Explorer, Threads and Stacks (Optional Free Tool)

Process Explorer is a free tool from Microsoft's Sysinternals set. It is not built into Windows. Download it only from Microsoft's official Sysinternals page.

  1. Start procexp64.exe. Run as administrator if you want to see system processes (it asks).

  2. Double-click a process, such as explorer.exe, then open the Threads tab.

  3. You will see each thread with its TID (thread ID), CPU use, cycles delta, and start address (the function it began in, for example ntdll.dll!TppWorkerThread).

  4. Click one thread, then click the Stack button. You will see a list of function names, newest call at the top. This is the call stack (the thread's private stack from Section 6.3) turned into names.

  5. Pick a thread with a TppWorkerThread start address. What does that suggest it is? ________________ (A worker in the Windows thread pool, Section 9.)

  6. In its stack, which function is at the top? Is it something like NtWaitForWorkViaWorkerFactory (the thread is waiting for a task)? ________________

If symbols are not set up, some entries show as plain addresses. That is normal. Process Explorer can load them if you configure Microsoft's symbol server under Options → Configure Symbols.

What Should Happen

  • A normal PC shows hundreds of processes and thousands of threads in total.
  • Most threads show Wait. Only a few are Running at any time (never more than your logical processors).
  • Idle Processor Queue Length is near 0.
  • Browsers and big apps have dozens to hundreds of threads. Tiny apps have only a handful.

Interpretation Guide

What you seeWhat it means
Threads ÷ processes ≈ 10 to 15Typical desktop; many background services
Most threads in WaitHealthy. They sleep until they have work
Many threads with start address TppWorkerThreadThe program uses the Windows thread pool
Processor Queue Length often over 2 per coreThe CPU has more ready threads than cores
A process's thread count keeps growing and never fallsA possible thread leak (a bug)
Handles count growing along with threadsLikely a handle leak: closing handles was forgotten
Hung program with CPU near 0 and a wait-chain loopA deadlock
Hung program with CPU at 100% on one coreAn endless loop (a livelock-like or plain bug)
BasePriority 8Normal class, Normal thread

Follow-Up Questions

  1. Why can a PC with 8 logical processors have more than 2,000 threads, yet only 8 are ever Running at once?
  2. A program shows 40 threads, 38 of them in Wait. Is that a problem? Why or why not?
  3. You see 1,000 context switches per second while idle and 30,000 while compiling code. Is that surprising?
  4. Why would Analyze Wait Chain be useful for a program that is "Not Responding" while its CPU use is 0%?
  5. Name two facts from this lab that you could not have learned from just looking at the program's window.