Pausing a boost::thread for unlimited time

zitroneneis picture zitroneneis · Dec 16, 2010 · Viewed 7.4k times · Source

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

Answer

Adam Bowen picture Adam Bowen · Dec 16, 2010

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