Ожидание потока до тех пор, пока не будет выполнено условие

Я хочу подождать один поток из 2 потоков, который выполнялся в Simultaneous simulator до тех пор, пока не будет выполнено условие, может быть условие произошло после 1000 или более циклов запуска программы в симуляторе, после того, как условие произошло, выполняется снова, как я могу это сделать?

Ответы

Ответ 1

Вам нужны условные переменные.

Если ваш компилятор поддерживает std::conditional, введенный С++ 11, вы можете увидеть это для деталей:

Если ваш компилятор не поддерживает его, и вы работаете с потоками win32, см. это:

И здесь является полным примером.

И если вы работаете с потоками POSIX, см. это:


Вы можете увидеть мою реализацию conditional_variable с помощью примитивов win32:

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

Типичное использование условной переменной таково:

//lock the mutex first!
scoped_lock myLock(myMutex); 

//wait till a condition is met
myConditionalVariable.wait(myLock, CheckCondition);

//Execute this code only if the condition is met

где CheckCondition - функция (или функтор), которая проверяет условие. Он вызывается функцией wait() внутри, когда он ложно просыпается, и если условие еще не достигнуто, функция wait() снова спит. Перед сном wait() атомически высвобождает мьютекс.

Ответ 2

Если у вас нет С++ 11, но у вас есть система, которая поддерживает потоки POSIX, тогда вы можете использовать переменную условия. Существуют и другие варианты, но переменная состояния может быть наиболее прямой, учитывая то, как вы описали свою проблему.

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

  • получить мьютекс
  • пока PREDICATE не соответствует действительности
    • wait при условии переменной
  • работают в критическом разделе
  • если PREDICATE истинно
    • переменная состояния сигнала
  • релиз мьютекса

Шаг сигнала используется в том случае, если несколько потоков входят в один и тот же критический раздел выше.

Если другой поток может получить доступ к одному и тому же мьютексу для изменения состояния, которое влияет на PREDICATE, этот поток должен проверять, нужно ли кому-то сигнализировать.

  • получить мьютекс
  • работают в критическом разделе
  • если PREDICATE истинно
    • переменная состояния сигнала
  • релиз мьютекса

Интересные команды POSIX:

pthread_mutex_init()
pthread_mutex_destroy()
pthread_mutex_lock()
pthread_mutex_unlock()
pthread_cond_init()
pthread_cond_destroy()
pthread_cond_wait()
pthread_cond_signal()

Ответ 3

Использование Семафора для сигнализации. Пример (чистый выход приложения), как показано ниже:

Объявить в заголовке

static sem_t semPrepareExit;            //declaration

В источнике (основной поток);

sem_init(&semPrepareExit, 0, 0);        ///semaphore initialized
...
///now wait for the signal on the semaphore, to proceed hereforth
sem_post(&semPrepareExit);
/// cleanup ahead
...

В источнике, (порожденная-нить);

...
sem_post(&semPrepareExit);

Теперь, как только вы сигнализируете о семафоре с помощью "sem_post". Основной поток получит сигнал в wait- node/point и продолжит его дальше.

Ответ 4

попробуйте что-то вроде этого:

class CmyClass
{
   boost::mutex mtxEventWait;
   bool WaitForEvent(long milliseconds);
   boost::condition cndSignalEvent;
};

bool CmyClass::WaitForEvent(long milliseconds)
{
   boost::mutex::scoped_lock mtxWaitLock(mtxEventWait);
   boost::posix_time::time_duration wait_duration = boost::posix_time::milliseconds(milliseconds); 
   boost::system_time const timeout=boost::get_system_time()+wait_duration; 
   return cndSignalEvent.timed_wait(mtxEventWait,timeout); // wait until signal Event 
}

//поэтому, чтобы подождать, затем вызовите метод WaitForEvent

WaitForEvent(1000); // it will timeout after 1 second

//так можно сигнализировать событие:

cndSignalEvent.notify_one();