I am having trouble catching an interrupt in a worker thread. There are numerous boost thread interrupt posts on here but, they seem to be silly mistakes (which I'm sure my question is too), or something that didn't help
- Boost thread_interrupted exception terminate()s with MinGW gcc 4.4.0, OK with 3.4.5
- boost thread on interruption doesn't print exit message
- this example crashes Where to get simple Boost Thread Management example?
- My example is based off this, it still crashes How can I execute two threads asynchronously using boost?
In my example have a main thread that creates a worker thread. The main thread waits for the user to press enter while the worker thread is in a while loop, and sleeps for 1 second intervals. When the user presses enter the main thread interrupts the worker thread and then calls join, the worker thread should throw a thread_interrupted exception at boost::this_thread::sleep_for(sec) which should be caught and then the worker function should exit. This allows the main thread to continue and then exits the program.
#define BOOST_THREAD_USE_LIB 1
#define BOOST_SYSTEM_NO_DEPRECATED 1
#define _WIN32_WINNT 0x0501
#define WINVER 0x0501
#include <boost/thread.hpp>
#include <boost/chrono/include.hpp>
#include <boost/chrono/duration.hpp>
#include <iostream>
using namespace std;
void ThreadFunctionSleep()
{
cout << boost::this_thread::get_id() << " worker thread " << endl;
int counter = 0;
while(1)
{
cout << boost::this_thread::get_id() << " thread iteration " << ++counter << " Press Enter to stop" << endl;
try
{
boost::chrono::seconds sec(1);
boost::this_thread::sleep_for(sec);
}
catch(boost::thread_interrupted&)
{
cout << boost::this_thread::get_id() << " Thread is stopped in ThreadFunction " << endl;
return;
}
catch ( boost::thread_resource_error &)
{
cout << boost::this_thread::get_id() << " boost thread_resource_error" << endl;
return;
}
catch(...)
{
cout << boost::this_thread::get_id() << " worker func other" << endl;
return;
}
}
}
int main()
{
std::cout << boost::this_thread::get_id() << " main thread " << std::endl;
// Start thread
boost::thread t(&ThreadFunctionSleep);
// Wait for Enter
std::cout << boost::this_thread::get_id() << " Waiting for Enter" << std::endl;
char ch;
cin.get(ch);
// Ask thread to stop
//std::cout << t.get_id() << " joinable " << t.joinable() << std::endl;
try
{
t.interrupt();
}
catch(boost::thread_interrupted&)
{
std::cout << boost::this_thread::get_id() << " Thread is stopped" << std::endl;
}
catch ( boost::thread_resource_error &)
{
std::cout << boost::this_thread::get_id() << " boost thread_resource_error" << std::endl;
}
// Join - wait when thread actually exits
try
{
t.join();
}
catch(boost::thread_interrupted&)
{
std::cout << boost::this_thread::get_id() << " Thread is joined" << std::endl;
}
catch(boost::system::system_error &)
{
std::cout << boost::this_thread::get_id() << " boost system_error" << std::endl;
}
catch(...)
{
std::cout << boost::this_thread::get_id() << " other exception" << std::endl;
}
cout << boost::this_thread::get_id() << " main: thread ended" << endl;
return 0;
}
The output of my program I expect is something like this:
4f4 main thread
1264 worker thread
4f4 Waiting for Enter
1264 thread iteration 1 Press Enter to stop
1264 thread iteration 2 Press Enter to stop
1264 Thread is stopped in ThreadFunction
4f4 main: thread ended
Where the numbers in front is the thread ID. The problem is, I am not seeing this at all. There are 3 different ways the code executes after I press Enter. This suggests some sort of multithreaded problem that I'm not seeing.
No exception is caught until t.join(), the worker thread continues the executuion of the main thread
11cc main thread 11cc644 worker thread 644 thread iteration 1 Press Enter to stop Waiting for Enter 644 thread iteration 2 Press Enter to stop
644 Thread is joined 644 main: thread ended
Process returned 0 (0x0) execution time : 2.750 s Press any key to continue.
Program crashes
11cc main thread 11cc644 worker thread 644 thread iteration 1 Press Enter to stop Waiting for Enter 644 thread iteration 2 Press Enter to stop
644 Thread is joined 644 main: thread ended
Process returned 0 (0x0) execution time : 2.750 s Press any key to continue.
happens very rarely, but crashes anyway
11cc main thread 11cc644 worker thread 644 thread iteration 1 Press Enter to stop Waiting for Enter 644 thread iteration 2 Press Enter to stop
644 Thread is stopped in ThreadFunction
How do I catch boost::thread_interrupted in the worker thread so that the main thread will continue as normal?? On a similar note, will I need to consider anything else if I use a timed_wait() instead of sleep_for()??
I am using boost 1.53.0 and MinGW 4.4.1. I am using the runtime-link-static, multithreading libraries for boost::thread and boost::system
Thanks