我需要按需创建一些线程,因为我之前不知道我需要多少。
使用向量std::vector<std::thread> threads;
“存储”线程
每当我创建一个新线程时,我都会将它们推回向量:threads.push_back(std::thread(worker));
存储(用于测试)线程ID我使用以下内容:double test = std::hash<std::thread::id>()(std::this_thread::get_id());
根据cpp-references hash,thread::id和get_id,这应该可以正常工作。
但只有这一行我得到的ID总是0(零)
如果id在哈希行下面添加以下行,它会工作,我从线程中得到一个哈希的id:std::thread::id tid = std::this_thread::get_id();
即使我不使用tid
有人可以解释这种行为吗? 我正在使用eclipse juno并清理+重建项目几次......我只是不明白:/
这里的代码: (逐行,因为这里的格式规则是愚蠢的-.-
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;
}
答案 0 :(得分:5)
在x86_64上,double
的{{1}}参数将在不同的寄存器中传递给printf
参数,因此当您调用long
时,编译器会放置printf("%ld\n", test)
在浮点寄存器中调用该函数。然后test
实现在非浮点寄存器中查找参数,因为printf
转换说明符告诉它期望"%ld"
参数。因为实际参数与long int
查找的寄存器不在同一个寄存器中,所以无法找到该值。
当您添加下一行时,它会使printf
的值位于非浮点寄存器中,并且显然允许tid
找到它(但不依赖于此,它是未定义的行为且不可预测。)
解决方案:如果您无法正确使用printf
,请完全不要使用它。使用为printf
指定的正确转化,即double
或将值存储在其他类型中,或使用iostream。
答案 1 :(得分:2)
格式说明符不正确,因为%ld
是long
,而不是double
,因此程序具有未定义的行为。此外,std::hash<>::operator()
的返回值类型为size_t
,而非double
。请改为使用(类型安全)std::cout
:
auto test = std::hash<std::thread::id>()(std::this_thread::get_id());
std::cout << test << std::endl;
答案 2 :(得分:2)
您的输出错误。 %d
不适用于double
,代表十进制,即int
s。
你想要的是
printf("%f\n", test);
当然,如果您首先使用std::cout
,那么就不会发生这种情况,正如hmjd的回答所示。