zitroneneis
zitroneneis

Reputation: 1047

Pausing a boost::thread for unlimited time

I'm using the boost::thread library (V1.44) to support threads in my C++ project.

The user needs to be able to pause the execution of a test loop, that's running in its own thread, for an unlimited amount of time and be able to resume it whenever he pleases.

Under Windows I solved it like this

bool ContintueLoop(){
if(testLoopPaused){ //testLoopPaused can be set by the user via  GUI elements
  try{
      boost::this_thread::interruptible_wait( 2147483648 ); //that's very ugly,
      // somebody knows the right way to pause it for a unlimited time?
      return true;
     }
  catch( boost::thread_interrupted& e ){ //when the user selects resume the 
      // the thread is interrupted and continues from here
      testLoopPaused = false;
      return true;
     }
if( ... ) //test for other flags like endTestLoop etc.
  ....
}

This works without any problems, even though it would be nice to know the correct value for an unlimited interruption.

I started to implement a linux version of my program, but I ran into the problem that I get the compiler error

error: interruptible_wait is not a member of boost::this_thread

Question: What's a good way to pause a boost::thread for an unlimited time (until the user decides to resume it)

Thank you very much

Upvotes: 10

Views: 8028

Answers (2)

Krzych
Krzych

Reputation: 83

If anybody still needs mentioned functionality (sleeping thread until an event occurs) and is comfortable using boost libraries then Boost.Interprocess library provides Semaphore mechanism which can be used as described in question.

Upvotes: 1

Adam Bowen
Adam Bowen

Reputation: 11230

I'm not aware of any way to pause a thread at an arbitrary point using boost::thread, however, the situtation you've described can be implemented using a boolean, mutex and condition variable.

bool m_pause; // initialise to false in constructor!
boost::mutex m_pause_mutex;
boost::condition_variable m_pause_changed;

void block_while_paused()
{
    boost::unique_lock<boost::mutex> lock(m_pause_mutex);
    while(m_pause)
    {
        m_pause_changed.wait(lock);
    }
}

void set_paused(bool new_value)
{
    {
        boost::unique_lock<boost::mutex> lock(m_pause_mutex);
        m_pause = new_value;
    }

    m_pause_changed.notify_all();
}

So, in your worker thread you can periodically call block_while_paused() which won't return until m_pause is set to false. In your main thread you call set_paused(value) to update the value of the pause variable in a thread safe manner.

Disclaimer: This is adapted from some similar code we have here, but I haven't tried to compile the adapted code, let alone verify it actually works :)

Upvotes: 19

Related Questions