Приостановка повышения :: поток на неограниченное время - PullRequest
10 голосов
/ 16 декабря 2010

Я использую библиотеку boost :: thread (V1.44) для поддержки потоков в моем проекте C ++.

Пользователь должен иметь возможность приостановить выполнение цикла тестирования, который выполняется в своем собственном потоке, на неограниченное количество времени и сможет возобновить его, когда пожелает.

Под Windows я решил это так

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

Это работает без проблем, хотя было бы неплохо узнать правильное значение для неограниченного прерывания.

Я начал реализовывать версию моей программы для Linux, но столкнулся с проблемой что я получаю ошибку компилятора

ошибка: interruptible_wait не является членом boost::this_thread

Вопрос: Какой хороший способ приостановить повышение :: thread на неограниченное время (пока пользователь не решит возобновить его)

Большое спасибо

Ответы [ 2 ]

18 голосов
/ 16 декабря 2010

Я не знаю ни одного способа приостановить поток в произвольной точке, используя boost :: thread, однако описанная вами ситуация может быть реализована с использованием логической переменной, мьютекса и условной переменной.

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();
}

Итак, в вашем рабочем потоке вы можете периодически вызывать block_while_paused(), который не будет возвращаться, пока m_pause не будет установлено в false.В вашем основном потоке вы вызываете set_paused(value), чтобы обновить значение переменной pause потокобезопасным способом.

Отказ от ответственности: Это адаптировано из некоторого подобного кода, который мы здесь, но я не пытался скомпилироватьадаптированный код, не говоря уже о том, что он действительно работает:)

1 голос
/ 30 января 2014

Если кому-то все еще нужны упомянутые функции (спящий поток, пока событие не происходит) и им удобно использовать библиотеки повышения, тогда библиотека Boost.Interprocess предоставляет механизм Семафор , который можно использовать, как описано в вопрос.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...