C++ 线程未加入 "Termination called without active exception"

标签 c++ linux multithreading c++11

我试图通过使用 std::thread 来加速 for 循环。循环遍历包含数百万项的列表。我将每次迭代分配给不同的线程。

在 4047 次迭代后,它停止运行并抛出 terminate called without an active exception Aborted (core dumped)

我认为此错误通常是由于未正确连接线程引起的(如本网站其他问题所述)。但是,我确实有一个函数可以在我的 for 循环结束时加入所有线程。因为没有达到连接功能,我怀疑真正的问题是创建了太多线程。这是我第一次涉足 lambda 和多线程,我不确定如何限制在 for 循环中一次创建的线程数。

我的代码如下:

std::mutex m;
std::vector<std::thread> workers;
for ( ot.GoToBegin(), !ot.IsAtEnd(); ++ot )  // ot is the iterator
{
    workers.push_back(std::thread([test1, test2, ot, &points, &m, this]() 
    {
        // conditions depending on the current ot are checked
        if ( test1 == true ) return 0;  // exit function
        if ( test2 == true ) return 0;
        // ...etc, lots of different checks are performed..

        // if conditions are passed save the current ot
        m.lock();
        points.push_back( ot.GetIndex() );
        m.unlock();
    }));
} // end of iteration
std::for_each(workers.begin(), workers.end(), [](std::thread &t) 
{
    t.join();  // join all threads
});

任何帮助将不胜感激

最佳答案

由于您每次都在相同的迭代中遇到错误,原因不在于“join”本身。很可能,系统上每个进程的线程数受 4096 或类似数字的限制,请参阅 Maximum number of threads per process in Linux?

当您创建线程号 4047 左右时,std::thread 的构造函数会抛出异常,您永远不会进入“join”语句。

我建议您保留一个不是 std::tread(s) 而是 std::future(s) 的 vector 。代码大致如下所示:

typedef std::future<int> Future;
std::vector<Future> results;
for (...) {
    results.emplace_back( std::async(std::launch::async, 
     [...](){ /* roughly same code as in your thread function */ }) );
}
for ( Future& result : results) {
    auto value = result.get(); //waits for the task to finish 
    // process your values ...
}

future 依赖于内部线程池,因此您不会用完线程。这些 future 将在线程可用时异步执行。

关于C++ 线程未加入 "Termination called without active exception",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42126676/

相关文章:

c++ - 如何在 C++ 中找到任意方向的最小边界框

linux - 如何让 cg_annotate 包含字典?

linux - 识别(并删除)所有子目录中超过 1 帧的所有 .gif 文件

ios - 是否可以启动更高优先级的应用程序?

c++ - 模板类型的引用是什么意思?

c++ - 一个doxygen eclipse插件自动生成 stub 文档?

c++ - 如何验证 Internet 打印协议(protocol) (IPP)?

linux - 启动代码——用于 ARM 的 linux IRQ 中断处理程序

java - 将特定线程绑定(bind)到特定处理器内核

java - 线程行为:Java Beginner