1

我需要按需创建一些线程,因为我之前不知道我需要多少。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 hashthread::idget_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;
}
4

3 回答 3

5

在 x86_64 上,double参数 toprintf将在不同的寄存器中传递给long参数,因此当您调用printf("%ld\n", test)编译器时,会放入test一个浮点寄存器并调用该函数。然后printf实现在非浮点寄存器中查找参数,因为"%ld"转换说明符告诉它期待一个long int参数。因为实际参数与查找的寄存器不在同一个寄存器printf中,所以它无法找到该值。

当您添加下一行时,它会导致值tid位于非浮点寄存器中,并且显然允许printf找到它(但不要依赖它,它是未定义的行为且不可预测。)

解决方法:如果不能printf正确使用,就不要使用了。要么使用为doubleie指定的正确转换,"%f"要么将值存储在不同的类型中,或者使用 iostreams。

于 2013-06-03T17:20:42.160 回答
2

格式说明符与 a 不正确%ldlong而不是 a 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;
于 2013-06-03T14:54:02.140 回答
2

你的输出是错误的。%d不是for double,它代表十进制,即ints。

你想要的是

printf("%f\n", test);

当然,如果您只是std::cout按照 hmjd 的回答所建议的那样首先使用,那么这一切都不会发生。

于 2013-06-03T14:54:44.290 回答