terminate called recursively - c++

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.

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".

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

Related

Receive async exception directly

class ClassA
{
void running()
{
int count = 0;
m_worker_stop.store(true);
while (m_worker_stop.load() == false)
{
count++;
if (count == 10)
{
// Make exception
std::vector v(100000000000);
}
}
}
void start()
{
m_worker = std::async(std::launch::async, &ClassA::running, this);
}
void stop()
{
m_worker_stop.store(true);
if (m_worker.valid())
m_worker.get(); // catch exception in this point
}
std::future<void> m_worker;
std::atomic_bool m_worker_stop = { false };
}
class Main // this is single-ton Main class
{
...
void running()
{
try {
m_classA->start();
// Wait for external signal(ex. SIGINT, SIGTERM, ..)
while (true) { // signal check }
m_classA->stop();
}
catch(std::exception& e) {
// re-create throwed object
}
catch(...) {
// re-create throwed object
}
}
}
int main()
{
Manager::getInstance()::running();
return 0;
}
Hello, everyone.
The approximate structure of the program is as above.
In fact, I have not only classA but also many other objects such as B, C, and D.
(start() and stop() function is simillar !)
An exception was raised using std::vector v(1000000..)
However, it became a catch when stop() was activated.
What I actually want is to delete the classA object and re-create it if an exception occurs.
So I need to catch directly when exception was occured.
In this case, is any idea to get exception without wait for signals?
Here is one way of achieving the effect you want:
class Main // this is single-ton Main class
{
...
void running()
{
for (size_t i = 0; i < max_tries; ++i)
{
try {
m_classA->start();
// Wait for external signal(ex. SIGINT, SIGTERM, ..)
while (true) {
// signal check ...
}
m_classA->stop();
// path to happy ending :)
LOG("Main::running(): Operation successful.",
return;
}
catch(std::exception& e) {
LOG("Main::running(): Exception caught: message:\"{}\"", e.what());
}
catch(...) {
LOG("Main::running(): Unspecified exception caught, aborting.");
return; // Example of 'unrecoverable error'
}
// this part is only executed after an exception.
m_classA->shut_down(); // if you need some special shut down after an error.
m_classA.clear(); // this is redundant, but explicit (optional)
m_classA = MakeMeAnA(); // call our favorite A construction method.
}
// path to total failure :(
LOG("Main::running(): Exiting after {} failed attempts", max_tries);
}
private:
static constexpr size_t max_tries = 3;
};

std::async thread pool continue execution without blocking

I have a Thread Pool where each thread must be a waiting thread and keep listening to new tasks to process them asynchronously (the processing takes some long time). However, in the following code I am not able to get this behaviour. The problem is that when I create the thread pool, they execute successfully the first task given. The process() function reaches de return 0; while threads are computing tasks, but it never returns to main(). It stands in the v.wait(l, [&] {return !tasks.empty(); }); line, that is, it still waits for new tasks to be pushed into the tasks queue and that never happens. I've readed that it's something related to the std::future destructor: If I am not wrong, I think that when process() reaches the return, the std::future destructor is called and it waits till all the threads ends, but they never ends!
Here's the code:
static int callings = 0;
class ThreadPool
{
private:
std::queue<int> tasks;
std::mutex m;
std::vector<std::future<void>> finished;
std::condition_variable v;
public:
void push_task(int arg) {
std::unique_lock<std::mutex> l(m);
tasks.push(arg);
v.notify_one(); // wake a thread to work on the task
}
void read_tasks() {
while (true) {
std::unique_lock<std::mutex> l(m);
if (tasks.empty()) {
//waits till new task
v.wait(l, [&] {return !tasks.empty(); }); //after completing the first task, the program stays here forever
}
int task = tasks.front(); // read task
tasks.pop(); //delete task
//run the task
std::this_thread::sleep_for(std::chrono::milliseconds(5 * 1000)); //simulate computation
}//while true
}
void create_thread_pool(int m_threads_count) {
for (int t_i = 0; t_i < m_threads_count; t_i++) {
finished.push_back(std::async(std::launch::async,[this] { read_tasks(); }));
printf("Thread %d is doing work...\n", t_i);
}
}
}; //ThreadPool
int process(){
ThreadPool pool;
if(callings == 0)
{
pool.create_thread_pool(4);
}
//give some task to do...
pool.push_task(callings);
callings++;
return 0; //point reached but never returning to main
}
int main(){
while(true){
// do things...
process();
// do more things...
// this does not execute, how to solve this?
}
return 0;
}
How can I return to main() while the threads keep waiting for new tasks without blocking?
Thanks in advance

Thread synchronization problem in thread's procedure

I have a question. I add the object to the map and in the thread call the run() procedure for all elements in the map.
I correctly understand that in this code there is a synchronization problem in the process procedure. Can I add a mutex? Given that this procedure is called in the thread?
class Network {
public:
Network() {
std::cout << "Network constructor" << std::endl;
}
void NetworkInit(const std::string& par1) {
this->par1 = par1;
}
~Network() {
std::cout << "Network destructor" << std::endl;
my_map.clear();
}
void addLogic(uint32_t Id, std::shared_ptr<Logic> lgc) {
std::lock_guard<std::mutex> lk(mutex);
my_map.insert(std::pair<uint32_t, std::shared_ptr<Logic>>(Id, lgc));
cv.notify_one();
}
void removeLogic(uint32_t Id) {
std::unique_lock<std::mutex> lk(mutex);
cv.wait(lk, [this]{return !my_map.empty(); });
auto p = this->my_map.find(roomId);
if (p != end(this->my_map)) {
this->my_map.erase(roomId);
}
lk.unlock();
}
/**
* Start thread
*/
void StartThread(int id = 1) {
running = true;
first = std::thread([this, id] { process(id); });
first.detach();
}
/**
* Stop thread
*/
void StopThread() {
running = false;
}
private:
std::thread first;
std::atomic<bool> running = ATOMIC_VAR_INIT(true);
void process(int id) {
while (running) {
for (const auto& it:my_map) {
it.second->run();
}
std::this_thread::sleep_for(10ms);
}
}
private:
std::mutex mutex;
std::condition_variable cv;
using MyMapType = std::map<uint32_t, std::shared_ptr<Logic> >;
MyMapType my_map;
std::string par1;
};
The first idea is to protect the map as a whole with a mutex that is released during run. This works for addLogic because inserting into a map invalidates no iterators, but not for deleteLogic which might invalidate the very iterator value being used by process.
More efficient, lock-free approaches like hazard pointers may be applicable here, but the basic idea is to use a deferred deletion list. Assuming that the intent of concurrent deletion is cancellation of the task (not merely cleanup after all work is completed), it’s sensible to have the consumer thread to check immediately before execution. Using a set (to correspond to your map) will let the deletion list be dynamic and those checks be efficient.
So have another mutex protect the deletion list and take it at the beginning of each iteration in process:
void addLogic(uint32_t Id, std::shared_ptr<Logic> lgc) {
std::lock_guard<std::mutex> lk(mutex);
my_map.insert(std::pair<uint32_t, std::shared_ptr<Logic>>(Id, lgc));
}
void removeLogic(uint32_t Id) {
std::lock_guard<std::mutex> kg(kill_mutex);
kill.insert(Id);
}
private:
std::set<uint32_t> kill;
std::mutex mutex,kill_mutex;
void process(int id) {
for(;running;std::this_thread::sleep_for(10ms)) {
std::unique_lock<std::mutex> lg(mutex);
for(auto i=my_map.begin(),e=my_map.end();i!=e;) {
if(std::lock_guard<std::mutex>(kill_mutex),kill.erase(i->first)) {
i=my_map.erase(i);
continue; // test i!=e again
}
lg.unlock();
i->second->run();
lg.lock();
++i;
}
}
}
This code omits your condition_variable usage: it’s not necessary to wait before enqueuing something for deletion.
The solution with low level concurrency primitives usually does not scale and is not easy to maintain.
A better alternative would be to have a thread-safe "control" queue of map update or worker termination instructions.
Something like this:
enum Op {
ADD,
DROP,
STOP
};
struct Request {
Op op;
uint32_t id;
std::function<void()> action;
};
...
// the map which required protection in your code
std::map<uint32_t, std::function<void()>> subs;
// requests queue and its mutex (not very optimal, just to demonstrate the idea)
std::vector<Request> requests;
std::mutex mutex;
// the worker thread
std::thread worker([&](){
// the temporary buffer where requests are drained to from the queue before processing
decltype(requests) buffer;
// the main loop
while (true) {
// requests collection (requires synchronization)
{
std::lock_guard<decltype(mutex)> const guard {mutex};
buffer.swap(requests);
}
// requests processing
for(auto&& request: buffer) {
switch (request.op) {
case ADD:
subs[request.id] = std::move(request.action);
break;
case DROP:
subs.erase(request.id);
break;
case STOP: goto endloop;
}
}
// map iteration
for (auto&& entry: subs) {
entry.second();
}
}
endloop:;
});

Thread join hangs

Thread join is hanging in case of single producer and multiple consumer case.
I am attaching the codebase below:
1) This is the Consumer Thread
class ConsumerThread-
{
wqueue<WorkItem*>& m_queue;
-
public:
ConsumerThread(wqueue<WorkItem*>& queue) : m_queue(queue) {}
std::thread start() {
return std::thread( [=] {runThr();} );
}
-
void runThr() {
// Remove 1 item at a time and process it. Blocks if no items are-
// available to process.
for (int i = 0;; i++) {
printf("thread %lu, loop %d - waiting for item...\n",-
std::this_thread::get_id(), i);
WorkItem* item = (WorkItem*)m_queue.remove();
printf("thread %lu, loop %d - got one item\n",-
std::this_thread::get_id(), i);
printf("thread %lu, loop %d - item: message - %s, number - %d\n",-
std::this_thread::get_id(), i, item->getMessage(),-
item->getNumber());
delete item;
}
}
};
2) This is Work Item
class WorkItem
{
std::string m_message;
int m_number;
-
public:
WorkItem(const char* message, int number)-
: m_message(message), m_number(number) {}
~WorkItem() {}
-
const char* getMessage() { return m_message.c_str(); }
int getNumber() { return m_number; }
};
3). This class is has the queue where the producer pushes and consumers consume the WorkItem.
template <typename T> class wqueue
{
std::list<T> m_queue;
std::mutex m_mutex;
std::condition_variable m_condv;-
public:
wqueue() {}
~wqueue() {}
void add(T item) {
m_mutex.lock();
m_queue.push_back(item);
m_condv.notify_one();
m_mutex.unlock();
}
T remove() {
std::unique_lock<std::mutex> lk(m_mutex);
while(m_queue.size() == 0)
m_condv.wait(lk);
T item = m_queue.front();
m_queue.pop_front();
return item;
}
int size() {
m_mutex.lock();
int size = m_queue.size();
m_mutex.unlock();
return size;
}
};
4) This is the class containing the main function
int main(int argc, char* argv[])
{
// Process command line arguments
if ( argc != 2 ) {
printf("usage: %s <iterations>\n", argv[0]);
exit(-1);
}
int iterations = atoi(argv[1]);
// Create the queue and consumer (worker) threads
wqueue<WorkItem*> queue;
ConsumerThread* thread1 = new ConsumerThread(queue);
ConsumerThread* thread2 = new ConsumerThread(queue);
std::thread t1 = thread1->start();
std::thread t2 = thread2->start();
t1.join();
t2.join();
// Add items to the queue
WorkItem* item;
for (int i = 0; i < iterations; i++) {
item = new WorkItem("abc", 123);
queue.add(item);
item = new WorkItem("def", 456);
queue.add(item);
item = new WorkItem("ghi", 789);
queue.add(item);
}
The t1.join() and t2.join() hangs mentioned in the section 4.
Your consumer thread has no terminating condition so it runs forever:
for (int i = 0;; i++) // never ends
Joining a thread won't magically make it break out of its loop, you need to set an ended flag or something.
Also when the wqueue is empty all threads trying to remove() an element will block:
while(m_queue.size() == 0)
m_condv.wait(lk);
You try to join() the threads before putting anything in them.
There is nothing wrong with the behaviour, calling join() on a thread object will simply wait until the thread finishes before continuing. Your problem is rather that your threads don't terminate, which is a whole different issue.
In particular in a producer-consumer setup, both peers typically sit and wait for work. Unless you explicitly tell them not to wait for work any longer, they will sit there forever! If you in turn wait for them to finish, you will also wait forever, which is your problem. You need to signal them to stop looping and additionally you might have to interrupt them from waiting for work.

Shutdown boost threads correctly

I have x boost threads that work at the same time. One producer thread fills a synchronised queue with calculation tasks. The consumer threads pop out tasks and calculates them.
Image Source: https://www.quantnet.com/threads/c-multithreading-in-boost.10028/
The user may finish the programm during this process, so I need to shutdown my threads properly. My current approach seems to not work, since exceptions are thrown. It's intented that on system shutdown all processes should be killed and stop their current task no matter what they do. Could you please show me, how you would kill thoses threads?
Thread Initialisation:
for (int i = 0; i < numberOfThreads; i++)
{
std::thread* thread = new std::thread(&MyManager::worker, this);
mThreads.push_back(thread);
}
Thread Destruction:
void MyManager::shutdown()
{
for (int i = 0; i < numberOfThreads; i++)
{
mThreads.at(i)->join();
delete mThreads.at(i);
}
mThreads.clear();
}
Worker:
void MyManager::worker()
{
while (true)
{
int current = waitingList.pop();
Object * p = objects.at(current);
p->calculateMesh(); //this task is internally locked by a mutex
try
{
boost::this_thread::interruption_point();
}
catch (const boost::thread_interrupted&)
{
// Thread interruption request received, break the loop
std::cout << "- Thread interrupted. Exiting thread." << std::endl;
break;
}
}
}
Synchronised Queue:
#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>
template <typename T>
class ThreadSafeQueue
{
public:
T pop()
{
std::unique_lock<std::mutex> mlock(mutex_);
while (queue_.empty())
{
cond_.wait(mlock);
}
auto item = queue_.front();
queue_.pop();
return item;
}
void push(const T& item)
{
std::unique_lock<std::mutex> mlock(mutex_);
queue_.push(item);
mlock.unlock();
cond_.notify_one();
}
int sizeIndicator()
{
std::unique_lock<std::mutex> mlock(mutex_);
return queue_.size();
}
private:
bool isEmpty() {
std::unique_lock<std::mutex> mlock(mutex_);
return queue_.empty();
}
std::queue<T> queue_;
std::mutex mutex_;
std::condition_variable cond_;
};
The thrown error call stack:
... std::_Mtx_lockX(_Mtx_internal_imp_t * * _Mtx) Line 68 C++
... std::_Mutex_base::lock() Line 42 C++
... std::unique_lock<std::mutex>::unique_lock<std::mutex>(std::mutex & _Mtx) Line 220 C++
... ThreadSafeQueue<int>::pop() Line 13 C++
... MyManager::worker() Zeile 178 C++
From my experience on working with threads in both Boost and Java, trying to shut down threads externally is always messy. I've never been able to really get that to work cleanly.
The best I've gotten is to have a boolean value available to all the consumer threads that is set to true. When you set it to false, the threads will simply return on their own. In your case, that could easily be put into the while loop you have.
On top of that, you're going to need some synchronization so that you can wait for the threads to return before you delete them, otherwise you can get some hard to define behavior.
An example from a past project of mine:
Thread creation
barrier = new boost::barrier(numOfThreads + 1);
threads = new detail::updater_thread*[numOfThreads];
for (unsigned int t = 0; t < numOfThreads; t++) {
//This object is just a wrapper class for the boost thread.
threads[t] = new detail::updater_thread(barrier, this);
}
Thread destruction
for (unsigned int i = 0; i < numOfThreads; i++) {
threads[i]->requestStop();//Notify all threads to stop.
}
barrier->wait();//The update request will allow the threads to get the message to shutdown.
for (unsigned int i = 0; i < numOfThreads; i++) {
threads[i]->waitForStop();//Wait for all threads to stop.
delete threads[i];//Now we are safe to clean up.
}
Some methods that may be of interest from the thread wrapper.
//Constructor
updater_thread::updater_thread(boost::barrier * barrier)
{
this->barrier = barrier;
running = true;
thread = boost::thread(&updater_thread::run, this);
}
void updater_thread::run() {
while (running) {
barrier->wait();
if (!running) break;
//Do stuff
barrier->wait();
}
}
void updater_thread::requestStop() {
running = false;
}
void updater_thread::waitForStop() {
thread.join();
}
Try moving 'try' up (like in the sample below). If your thread is waiting for data (inside waitingList.pop()) then may be waiting inside the condition variable .wait(). This is an 'interruption point' and so may throw when the thread gets interrupted.
void MyManager::worker()
{
while (true)
{
try
{
int current = waitingList.pop();
Object * p = objects.at(current);
p->calculateMesh(); //this task is internally locked by a mutex
boost::this_thread::interruption_point();
}
catch (const boost::thread_interrupted&)
{
// Thread interruption request received, break the loop
std::cout << "- Thread interrupted. Exiting thread." << std::endl;
break;
}
}
}
Maybe you are catching the wrong exception class?
Which would mean it does not get caught.
Not too familiar with threads but is it the mix of std::threads and boost::threads that is causing this?
Try catching the lowest parent exception.
I think this is a classic problem of reader/writer thread working on a common buffer. One of the most secured way of working out this problem is to use mutexes and signals.( I am not able to post the code here. Please send me an email, I post the code to you).