i need to create some threads on demand because i dont know before how much i need.
To 'store' the threads im using a vector std::vector<std::thread> threads;
every time i create a new thread i push them back on the vector: threads.push_back(std::thread(worker));
to store (for testing) the thread id i use the following: double test = std::hash<std::thread::id>()(std::this_thread::get_id());
according to the cpp-references hash, thread::id and get_id this should work fine.
but only with this line im getting as id always a 0 (zero)
if id add the following line below the hash line it works and i get a hashed id from the thread: std::thread::id tid = std::this_thread::get_id();
even i dont use tid
can someone explain this behavior? im working with eclipse juno and cleaned + rebuild the project several times...i just dont get it :/
here the code: (line by line because those format rules here are stupid -.-
std::vector<std::thread> threads;
void worker (){
double test = std::hash<std::thread::id>()(std::this_thread::get_id());
std::thread::id tid = std::this_thread::get_id();
printf("%ld\n", test);
}
void joinThreads(std::thread& t)
{
t.join();
}
int main() {
for (int i = 0; i < 10; ++i) {
threads.push_back(std::thread(worker) );
}
std::for_each(threads.begin(),threads.end(),joinThreads);
return 0;
}
On x86_64 a double
argument to printf
would be passed in a different register to a long
argument, so when you call printf("%ld\n", test)
the compiler puts test
in a floating point register and calls the function. The printf
implementation then looks for the argument in a non-floating point register because the "%ld"
conversion specifier tells it to expect a long int
argument. Because the actual argument is not in the same register as printf
looks in, it fails to find the value.
When you add the next line it causes the value of tid
to be in a non-floating point register, and apparently that allows printf
to find it (but don't rely on that, it's undefined behaviour and unpredictable.)
Solution: If you can't use printf
correctly then don't use it at all. Either use the right conversion specified for double
i.e. "%f"
or store the value in a different type, or use iostreams.