我正在尝试在循环中创建不同的线程,然后将它们存储在线程的向量中。
编辑1 :用户指定线程的数量。
const int numThreads = stoi(argv[3]);
初始代码:
vector<thread> vectorThreadsFFT{(unsigned long) (numThreads)};
for (int i = 0; i < numThreads; ++i) {
vectorThreadsFFT.emplace_back(
move(thread{FFT, ref(vectorBuffersUC), ref(vectorBuffersCD), ref(i), ref(numThreads)}));
}
编辑2:我在结尾处加入线程。
for (int i = 0; i < numThreads; ++i) {
vectorThreadsFFT[i].join();
}
当我调试代码时,会得到分段故障(Signal = Sigabrt)。我已经尝试通过push_back()
删除移动子句并更改emplace_back()
,但是我仍然得到相同的结果。
编辑3:有时(但不是每次)仅创建一个线程的另一个函数,例如:
thread th2{separator, ref(vectorBuffersUC), ref(numThreads), ref(nitems)};
哪个标头如下:
void separator(vector<unique_ptr<lockedBufferUC>> &vectorBuffersUC, int numThreads, const long nitems){}
我开始怀疑这是因为我要给向量的参数以及函数如何接收它们。
我是否缺少有关C 11和线程管理的内容?
随时要求提供更多详细信息或代码。
解决方案尝试:
- 保留空间
- 通过value的i传递i
代码不执行您期望的事情。
vector<thread> vectorThreadsFFT{(unsigned long) (numThreads)};
这正确调整了向量以容纳numThreads
元素。但是,这种初始化后面是emplace_back
或push_back
,将在numThreads
索引上添加一个元素,而在0
处添加。
在这里要做的少数正确的事情之一就是对向量进行reserve
,然后进行emplace_back
。
另外,不需要move
。使用优化编译器足够聪明,可以实现建筑。
另一件事是,除非您是detaching
,否则您必须join
线程。joinable
线程如果未加入破坏电话std::terminate
。
const int numThreads = stoi(argv[3]);
vector<thread> vectorThreadsFFT;
vectorThreadsFFT.reserve(numThreads);
for (int i = 0; i < numThreads; ++i) {
vectorThreadsFFT.emplace_back(
std::thread {FFT, ref(vectorBuffersUC), ref(vectorBuffersCD), i, ref(numThreads)} );
}
for (int i = 0; i < numThreads; ++i) {
vectorThreadsFFT.join();
}
您将引用到 i
的引用到螺纹的闭合,因此在循环结束后立即变得无效。尝试通过值来传递id
:
for (int i = 0; i < numThreads; ++i) {
vectorThreadsFFT.emplace_back(
thread{FFT, ref(vectorBuffersUC), ref(vectorBuffersCD), i, ref(numThreads)});
}
此外,您不应将std::move
用于RVALUE对象,例如thread{}
。
,正如@arunmu所述,您绝对不能忘记 join
vector毁灭之前的所有线程(这将导致terminate
,请参阅DOCS)。
更好的解决方案是使用std::async
不要手动处理加入。此外,它将允许您使用懒惰的执行和更好的并行可扩展方法(请参阅文档)。