我的问题非常简单。我有一个值向量(这里的线程,不相关),我想迭代它们。但是有两个版本的代码看起来与我相同,但只有第二个版本有效。我想知道原因。
版本1 (不编译)
int main(){
int someValue = 5;
vector<std::thread *> threadVector;
threadVector.resize(20);
for (int i = 0; i < 20; i++) {
threadVector[i] = new std::thread(foo, std::ref(someValue));
}
for (std::vector<std::thread *>::iterator it = threadVector.begin(); it != threadVector.end(); ++it) {
*it->join(); // *********Notice this Line*********
}
system("pause"); // I know I shouldn't be using this
}
第2版(有效)
int main(){
int someValue = 5;
vector<std::thread *> threadVector;
threadVector.resize(20);
for (int i = 0; i < 20; i++) {
threadVector[i] = new std::thread(foo, std::ref(someValue));
}
for (std::vector<std::thread *>::iterator it = threadVector.begin(); it != threadVector.end(); ++it) {
(*it)->join(); // *********Notice this Line*********
}
system("pause"); // I know I shouldn't be using this
}
答案 0 :(得分:3)
这是操作顺序的问题。
*it->join();
被解析为:
*(it->join());
答案 1 :(得分:1)
把它作为一个挑战,我第一次在C ++ 11中轻拍了一下。我发现你可以在没有动态分配std::thread
个对象的情况下实现相同的目标:
#include <iostream>
#include <thread>
#include <vector>
void function()
{
std::cout << "thread function\n";
}
int main()
{
std::vector<std::thread> ths;
ths.push_back(std::move(std::thread(&function)));
ths.push_back(std::move(std::thread(&function)));
ths.push_back(std::move(std::thread(&function)));
while (!ths.empty()) {
std::thread th = std::move(ths.back());
ths.pop_back();
th.join();
}
}
这是有效的,因为std::thread
有一个构造函数和赋值运算符,它采用右值引用,使其可移动。此外,所有容器都获得了对存储可移动对象的支持,并且它们移动而不是在重新分配时复制它们。阅读一些关于这个新的C ++ 11功能的在线文章,它在这里解释得太宽了,而且我也不太了解它。
关于您提出线程有内存成本的问题,我不认为您的方法是优化。相反,动态分配本身在内存和性能方面都有开销。对于小对象,一个或两个指针的内存开销加上可能的一些填充是巨大的。如果std::thread
对象只有一个指针的大小,给你的开销超过100%,我不会感到惊讶。
请注意,这仅涉及std::thread
对象。实际线程所需的内存,特别是其堆栈,是一个不同的问题。但是,std::thread
对象和实际线程没有1:1的关系,std::thread
对象的动态分配也不会改变任何内容。
如果您仍然担心重新分配过于昂贵,您可以预先保留合适的尺寸以避免重新分配。但是,如果这确实是一个问题,那么你创建和终止线程的方式太多了,到目前为止,这将使转移一些小对象的开销相形见绌。考虑使用线程池。