You can call ::get_id() to get the id of a thread, it is also possible to have two ids that are the same. And as far as I know ownership of threads is movable but not copyable, so how can two threads have the same id?
How can 2 threads have the same id?
Members - Reputation: 3407
Posted 25 May 2014 - 04:34 PM
I thought I had recently seen the answer to this; turns out, rip-off mentioned the answer in his reply to your earlier thread:
An initialized thread object represents an active thread of execution; Such a thread object is joinable, and has a unique thread id.
A default-constructed (non-initialized) thread object is not joinable, and its thread id is common for all non-joinable threads.
"We should have a great fewer disputes in the world if words were taken for what they are, the signs of our ideas only, and not for things themselves." - John Locke
Crossbones+ - Reputation: 8008
Posted 25 May 2014 - 05:00 PM
The wording of the standard is, as usual, a contorted, unintellegible, total mess for something that is actually very easy. Hence your confusion.
A thread object can refer to an actual thread, or it may not. A thread object may exist before the actual thread is created and beyond its lifetime, and it may lose "ownership" when it is moved, etc etc. Also, an acutal thread can obviously exist without a thread object.
If you query a thread object for its ID, then it depends on whether it corresponds to an actual thread. If it does, it returns that thread's ID (which is unique), otherwise it returns some bogus ID which is not a valid thread ID (since it doesn't correspond to a valid thread!). That bogus ID is (obviously) the same for all thread objects that don't correspond to an actual thread.
Edited by samoth, 25 May 2014 - 05:01 PM.
Crossbones+ - Reputation: 8008
Posted 26 May 2014 - 10:41 AM
Ugly situation though , does that happen?!
Actually this is not an ugly situation at all, but by design. The function get_id is declared to return a thread::id object, which means it must return one (a thread::id object is really just a mini-wrapper around a native_handle_type, which would e.g. be int32_t for Linux or void* for Windows, plus 3 or 4 convenience members like operator==).
It's the way functions work in C++. If you say that it returns something, say, an integer, then unless the function throws an exception, it has no choice but to actually return one.
But what do you return when there is no thread associated with the thread object? There is no meaningful value that you could return. So obviously, you return some default value, there's not much more you can do to it, but it's also not something that is nasty, it's just a concequence of the fact that you must return something.
Most probably that "magic value" will simply be zero, but the standard doesn't require that, it merely says that it's the same value for all non-joinable threads (this makes it identifiable, also it is a very practical constraint), and it's not a valid thread ID.
You can't do anything meaningful (other than compare it) with that ID, but that, too, is only normal. It doesn't make a lot of sense to query the ID of a thread object that doesn't correspond to a thread at all in the first place. However, since that function is declared, you are able to call it. No matter how nonsensical it may be, you can call this function, and it must work in a predictable, well-defined manner.
The way the standard is worded, it's guaranteed that you get something that is well-defined back in every case (not always useful, but always well-defined).
Edited by samoth, 26 May 2014 - 10:44 AM.