【问题标题】:terminate called recursively递归调用终止
【发布时间】:2012-09-03 02:25:11
【问题描述】:

据我所知,当异常处理出现问题时会调用terminate()(通常只是没有被捕获)。 我得到的只是一个错误行terminate called recursively

谷歌搜索了一段时间后,我发现了很多例子

terminate called after throwing an instance of ... terminate called recursively

但这不是我的情况。由于我没有关于异常类型的提示,我想知道这个 terminate called recursively 本身是什么意思。

抱歉,我无法提供代码,因此任何猜测都会有所帮助。 我在 Ubuntu 11.04 下使用 g++ 4.5.2 进行编译。

非常感谢, 亚历克斯。

【问题讨论】:

  • 没有代码我们什么也说不出来。可能是你有终止处理程序,它写着“递归调用终止”。
  • 感谢@ForEveR。不,我没有使用 set_terminate。
  • 尝试调试,使用gdb和core。

标签: c++ linux exception-handling


【解决方案1】:

可能是某些代码抛出了您没有捕获的异常,这意味着将调用terminate。终止程序意味着可能会调用对象析构函数,如果其中一个出现异常,则将“递归”调用terminate

【讨论】:

  • 仍然没有发现问题,但听起来很合理。谢谢!
  • 这不是答案。当析构函数在另一个异常的堆栈展开期间抛出异常时,该进程将立即终止。试试看。
  • “终止程序意味着可能会调用对象析构函数”——它们确实不应该。
【解决方案2】:

我遇到过这个问题,可能是thread poolthread中你的函数的error

让我们重复terminate called recursively exception

我正在用c++11写一个线程池,这是我的代码:

// blocking queue
template<typename T>
class SafeQueue{ 
    public:
        bool pop(T& value){
            std::lock_guard<std::mutex> lock(mtx_);
            if(queue_.empty())
                return false;

            value = queue_.front();
            queue_.pop_front();
            return true;
        }

        void push(T&& value){
            std::lock_guard<std::mutex> lock(mtx_);
            queue_.push_back(std::move(value));
        }

        bool empty(){
            std::lock_guard<std::mutex> lock(mtx_);
            return queue_.empty();
        }

    private:
        std::mutex mtx_;
        std::list<T> queue_;
};

typedef std::function<void()> Task;
typedef SafeQueue<Task> Tasks;

class ThreadPool{
    public:
        ThreadPool(uint32_t nums=5, bool start=false);
        ~ThreadPool();

        void start();
        void addTask(Task&& task);
        void join();
        void exit();
        size_t getThreadNum(){return threadNums_;}

    private:
        Tasks tasks_;

        std::vector<std::thread> threads_;
        size_t threadNums_;
        bool stop_;
};

ThreadPool::ThreadPool(uint32_t nums, bool start):
  threadNums_(nums), stop_(false)
{
    if(start)
        this->start();
}

ThreadPool::~ThreadPool(){
    stop_ = true;
}

void ThreadPool::start(){
    auto lb_thread_fun = [this](){
        while (!stop_){
            Task task;
            tasks_.pop(task);
            // error from here, task maybe empty.
            task();
        }
    };

    for (int i = 0; i < threadNums_; ++i) {
        threads_.push_back(std::thread(lb_thread_fun));
    }
}

void ThreadPool::addTask(Task&& task){
    tasks_.push(std::move(task));
}

void ThreadPool::join(){
    for (auto& th:threads_) {
        th.join();
    }
}

void ThreadPool::exit(){
    stop_ = true;
}

测试代码如下:

#include "my_threadpool.h"
#include <iostream>

using std::cout;
using std::endl;

auto lb_dummy_dw = [](const std::string& url){
    cout<<"start downloading: "<<url<<endl;
    std::this_thread::sleep_for(std::chrono::seconds(2));
    cout<<"downloading success !!!!"<<url<<endl;
};

auto lb_dummy_sql = [](int id, const std::string& name){
    cout<<"start select from db, id:" << id << ", name: "<<name<<endl;
    std::this_thread::sleep_for(std::chrono::seconds(3));
    cout<<"select db success !!!!"<<endl;
};

void test_thread_pool(){
    cout<<"create thread pool with 5 thread"<<endl;
    xy::ThreadPool tp(5);

    cout<<"add 3 * 2 task to thread pool"<<endl;
    for (int i = 0; i < 3; ++i) {
        tp.addTask(std::bind(lb_dummy_dw, "ww.xxx.com"));
        tp.addTask(std::bind(lb_dummy_sql, i, "xy" + std::to_string(i)));
    }

    cout<<"start thread pool"<<endl;
    tp.start();
    tp.join();
}

int main(){
    test_thread_pool();
    return 0;
}

当你运行上面的代码时,你可能会得到以下输出:

create thread pool with 5 thread
add 3 * 2 task to thread pool
start thread pool
start downloading: ww.xxx.com
start select from db, id:0, name: xy0
start downloading: ww.xxx.com
start select from db, id:1, name: xy1
start downloading: ww.xxx.com
downloading success !!!!ww.xxx.com
start select from db, id:2, name: xy2
downloading success !!!!ww.xxx.com
downloading success !!!!ww.xxx.com
terminate called recursively
terminate called after throwing an instance of 'std::bad_function_call'
  what():  

可以看到,它得到了terminate called recursively异常。因为在函数start中,变量task可能为空,所以thread pool中的每个线程都会抛出bad_function_call例外。

void ThreadPool::start(){
    auto lb_thread_fun = [this](){
        while (!stop_){
            Task task;
            tasks_.pop(task);
            // error from here, task maybe empty.
            task();
        }
    };

    for (int i = 0; i < threadNums_; ++i) {
        threads_.push_back(std::thread(lb_thread_fun));
    }
}

任务空测试代码如下:

void test_task(){
    Task task;
    try{
        task();
    }catch (std::exception& e){
        cout<<"running task, with exception..."<<e.what()<<endl;
        return;
    }

    cout<<"ending task, without error"<<endl;
}

输出如下:

running task, with exception...bad_function_call

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多