Ожидание потока до тех пор, пока не будет выполнено условие
Я хочу подождать один поток из 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();