2012-06-11 3 views
16

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

+1

Поиск условных переменных и семафоров. –

+0

Также посмотрите на обещания и фьючерсы (http://en.cppreference.com/w/cpp/thread/promise) –

ответ

23

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

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

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

И here - полный пример.

И если вы работаете с POSIX Threads, то увидите:


Вы можете увидеть мое внедрение 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() внутри, когда он spuriously просыпается, и если условие еще не достигнуто, функция wait() снова спит. Перед сном wait() высвобождает мьютексы, atomically.

5

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

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

  • приобретают мьютекс
  • в то время как PREDICATE не так
    • ожидания по условной переменной
  • работают на критической секции
  • если 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() 
1

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

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

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». Основной поток получит сигнал в узле-узле/точке и продолжит движение туда-сюда.

0

попробовать что-то вроде этого:

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(); 
Смежные вопросы