Skip to content

05 Aug 2026 3 min read

Which Thread on Which CPU Core

Let's verify how the Linux scheduler assigns threads to CPU cores using C++.

Let’s suppose your computer has 4 CPU cores and you decide to create 2 threads.

Will they be created on the same core or on different cores?

It sounds like a simple question, and you might already know the answer.

But how do we actually verify that answer with code?

Finding the Number of CPU Cores

C++ provides std::thread::hardware_concurrency(), which returns the number of hardware threads (logical CPUs) available to your program.

// num-of-cores.cc
#include <thread>
#include <iostream>

int main() {
    std::cout << "This system's CPU has "
              << std::thread::hardware_concurrency()
              << " cores\n";
    return 0;
}

Compile and run:

g++ num-of-cores.cc -std=c++20 -pthread
./a.out

The output on my machine looks like this:

Number of CPU cores

My machine reports 12 logical cores.


Finding Which Core a Thread Is Running On

Knowing how many CPU cores your machine has is nice, but the more interesting question is:

Which core is this thread running on?

One of the easiest ways on Linux is to use the <sched.h> header and call sched_getcpu().

// this-core.cc
#include <iostream>
#include <sched.h>

int main() {
    std::cout << "This thread is running on core "
              << sched_getcpu()
              << "\n";
}

Compile and run:

g++ this-core.cc -std=c++20
./a.out

On my machine, I got:

Current CPU core


You probably already know what’s coming next.

Let’s create multiple threads and see which CPU cores they actually get assigned to.

Creating Two Threads

// which-core.cc
#include <chrono>
#include <iostream>
#include <mutex>
#include <sched.h>
#include <thread>

std::mutex mtx;

// The mutex keeps our output readable.
// Without it, multiple threads may print at the same time.

void tell_core() {
    std::lock_guard<std::mutex> lock(mtx);

    std::cout << "Thread id: "
              << std::this_thread::get_id()
              << " got core "
              << sched_getcpu()
              << "\n";

    std::this_thread::sleep_for(std::chrono::microseconds(300));
}

int main() {
    std::thread t1(tell_core);
    std::thread t2(tell_core);

    t1.join();
    t2.join();

    return 0;
}

Compile and run:

g++ which-core.cc -std=c++20 -pthread
./a.out

The output on my machine:

Two threads on CPU cores

Notice that the two threads may be running on different CPU cores.

If you execute the program multiple times, you’ll likely notice that the assigned cores change from one run to another. That’s because the operating system’s scheduler decides where each thread runs, and it may even migrate a thread from one CPU core to another while the program is executing.


Your Turn

Now it’s your turn to experiment.

Instead of creating just two threads, create a vector of threads (or even better, a small thread pool) and try these three cases:

  1. Fewer threads than the number of CPU cores
  2. Exactly as many threads as CPU cores
  3. More threads than the number of CPU cores

Run the program several times and observe how your operating system schedules the threads.

I’d love to see your solutions.

If you get stuck, try searching the internet for answers. You’ll probably discover even more interesting things along the way. (That’s how many of us learn)

And of course, you’re always welcome to ask questions here.

Hope you had a great time reading this :)