在循环中创建线程向量的问题



我正在尝试在循环中创建不同的线程,然后将它们存储在线程的向量中。

编辑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_backpush_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不要手动处理加入。此外,它将允许您使用懒惰的执行和更好的并行可扩展方法(请参阅文档)。

相关内容

  • 没有找到相关文章

最新更新