8

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

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.

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

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

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

sehe
  • 374,641
  • 47
  • 450
  • 633
Andre
  • 115
  • 1
  • 7
  • You probably want to make sure that you synchronize your output. When printing to std::cout across multiple threads they might garble your output, making it significantly more difficult to decode. – villintehaspam Oct 31 '13 at 16:26

0 Answers0