terminate called recursively

南楼画角 提交于 2020-01-02 02:54:06

问题


As far as I know, terminate() is called when there is some problem with exception handling(usually it's just not caught). What I got is just one error line terminate called recursively.

After googling for some time I found a lot of examples of

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

But it's not my case. As I don't have this hint about the exception type, I'm wondering what does this terminate called recursively mean by itself.

Sorry I can't provide the code, so any guess will be helpful. I'm compiling with g++ 4.5.2 under Ubuntu 11.04.

Thanks a lot, Alex.


回答1:


Could be that some code throws an exception you don't catch, which means terminate will be called. Terminating the program means that object destructors might be called, and if there is an exception in one of them then terminate will be called "recursively".




回答2:


I have encounter this question, it's maybe the error of your function in thread pool or thread.

Let's recur the terminate called recursively exception.

I am writing a thread pool with c++11, here is my code:

// 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;
}

Test code as below:

#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;
}

When you run the above code, you may get the below output:

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():  

You can see, it got terminate called recursively exception. Because, in the function start, the variable task maybe empty, so each thread in the thread pool throw bad_function_call exception.

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

Task empty test code as below:

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

Output as below:

running task, with exception...bad_function_call


来源:https://stackoverflow.com/questions/12347981/terminate-called-recursively

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!