在没有活动异常线程c ++的情况下调用terminate

时间:2015-07-31 00:35:49

标签: c++ terminate

晚上好,我发现这个错误好几个小时,我找到了很多解决方案,但他们不能工作。

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();
}

2 个答案:

答案 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_backemplace_back。< / p>