5

In the following code, the .get_id() call returns the same value when run on CentOS; but on Windows, the same code returns different values.

Why?

#include <unistd.h>
#include <iostream>
#include <thread>

void dosomework()
{
    std::cout << std::this_thread::get_id() << std::endl;
}

int main()
{
    for (int i = 0; i < 10; ++i){
        std::thread connectthread([](){
            dosomework();
        });
        std::cout << "connectthread:" << connectthread.get_id() << std::endl;
        connectthread.join(); 
        sleep(1000);
    }
    return 0;
}
Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
JY Lee
  • 51
  • 2
  • 2
    Since each thread is joined before starting the next one, the most obvious explanation is that ids of terminated threads are simply recycled. – Sam Varshavchik Dec 31 '21 at 02:58
  • do you mean the id's printed by the `dosomework` function and the `connectthread.get_id()` part are different? – Fantastic Mr Fox Dec 31 '21 at 03:41
  • @FantasticMrFox Well, in my Windows system, those two values are the same for each thread (as they should be). Just that they are different from one loop to the next. – Adrian Mole Dec 31 '21 at 04:42

1 Answers1

3

Because of the connectthread.join(); call in your loop, each of your created threads will complete before another is started; thus, no two threads will be running at the same time.

Further, as stated on cppreference (bolding/emphasis mine)1; note that get_id() returns an object of std::thread::id class:

Instances of this class may also hold the special distinct value that does not represent any thread. Once a thread has finished, the value of std::thread::id may be reused by another thread.

The word, "may," means that is up to the implementation/platform to decide whether or not to re-use an ID of a completed thread for a new one. Thus, both the Windows and CentOS operating systems are complying with the requirements for the IDs of the threads you/they create.


1 The C++ Standard says much the same thing, though more obtusely. From this Draft C++17 Standard:

33.3.2.1 Class thread::id       [thread.thread.id]


1     An object of type thread::id provides a unique identifier for each thread of execution and a single distinct value for all thread objects that do not represent a thread of execution (33.3.2). Each thread of execution has an associated thread::id object that is not equal to the thread::id object of any other thread of execution and that is not equal to the thread::id object of any thread object that does not represent threads of execution.

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
  • Note that if you add a line like `std::cout << "dead thread:" << connectthread.get_id() << std::endl;` **after** the `join()` call, you will (or *should*) get the same ('special') value each time. On Windows, this is `0` for thread objects that don't represent a running thread. – Adrian Mole Dec 31 '21 at 04:55