Search code examples
c++multithreadingboostboost-thread

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


Solution

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