晚上好,我发现这个错误好几个小时,我找到了很多解决方案,但他们不能工作。
C_t是向量的向量,它的大小为100.如果循环为8,则它可以工作,但是当我增加它时,会抛出错误。
f是一个保存C_t评估的向量。
func是一种功能。
int nThreads = thread::hardware_concurrency(); // # threads
vector<thread> ths(nThreads); // threads vector
cout << ths.size() << endl;
//Launching threads
int idx = 0;
for ( int i = 0 ; i < 10 ; i++ ){
ths[idx] = thread( parallel_eval, ref(f[i]) , ref(C_t[i]) , func);
// idx = idx != nThreads ? idx++:0;
if(idx != nThreads){
idx++;
}
else{
idx = 0;
}
// std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
//Joining threads
for ( int i = 0; i < nThreads; i++ ){
ths[i].join();
}
答案 0 :(得分:2)
错误很可能是由ths
引起的。说明:
您可以节省硬件并发级别:
int nThreads = thread::hardware_concurrency();
您为线程对象创建容器:
vector<thread> ths(nThreads);
然后,您创建并保存最多N
个主题:
ths[idx] = thread( parallel_eval, ref(f[i]) , ref(C_t[i]) , func);
这是你的问题:
if(idx != nThreads)
{
idx++;
}
else
{
idx = 0;
}
此条件实质上意味着:“在当前索引下保存线程。如果我们达到nThreads
,请将索引设置为0
并继续保存。
因此,基本上,如果将N
的限制(循环的控制值和正在创建的线程数)设置为大于nThreads
的值,则覆盖线程对象(通过移动赋值运算符)。为什么这是一个问题?因为documentation说:
<强>的std ::螺纹::运算= 强>
使用移动语义将其他状态分配给
*this
。如果
*this
仍有关联的正在运行的主题(即joinable() == true
),则会调用std::terminate()
。
由于您覆盖的线程对象代表活动线程,因此满足调用std::terminate()
的条件。
此外,我们现在可以轻松说明每个n <= 8
的工作原理:您的 hardware_concurrency()
很可能 8 。
我会选择:
vector<thread> ths; //No need for any size restrictions. `vector<>` is a dynamic container, it will grow as necessary.
for ( int i = 0 ; i < 10 ; i++ )
{
ths.emplace_back(parallel_eval, ref(f[i]) , ref(C_t[i]) , func);
}
for (auto t = ths.begin(); t != ths.end(); ++t)
{
t->join();
}
答案 1 :(得分:0)
愿意把钱投入nThreads == 8.
如果是这种情况,vector<thread> ths(nThreads);
将在其内部数组中创建8个元素,并且ths[idx] = thread( parallel_eval, ref(f[i]) , ref(C_t[i]) , func);
将在第9个帖子中展开。
解决方案:将ths的初始大小锁定为您要创建的线程数,或者不要分配ths的初始大小以及线程的push_back
或emplace_back
。< / p>