2012-06-11 13 views
16

Quiero esperar un hilo de 2 hilos que se ejecutó en un simulador simultáneo hasta que se ha producido una condición, puede ser la condición ocurrida después de 1000 o más ciclos de ejecutar un programa en el simulador , después de que se produjo la condición, el hilo esperado se ejecutó de nuevo, ¿cómo puedo hacerlo?hilo de espera hasta que se haya producido una condición

+1

Variables condicionales y semáforos de búsqueda. –

+0

También eche un vistazo a las promesas y los futuros (http://en.cppreference.com/w/cpp/thread/promise) –

Respuesta

23

Necesita variables condicionales.

Si su compilador soporta std::conditional introducido por C++ 11, a continuación se puede ver esto por el detalle:

Si el compilador no lo soporta, y trabajar con hilos de Win32, a continuación, ver esto:

Y here es un ejemplo completo.

Y si se trabaja con los hilos POSIX, a continuación, ver esto:


Usted puede ver mi aplicación de conditional_variable usando primitivas Win32 aquí:

Desplácese hacia abajo y vea primero su implementación, luego vea el uso en la implementación de la cola concurrente.

Un uso típico de la variable condicional es esto:

//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 

donde CheckCondition es una función (o funtor) que comprueba la condición. Se llama por wait() funciona internamente cuando espuria se despierta y si la condición no se ha cumplido aún, la función wait() duerme nuevamente. Antes de ir a dormir, wait() libera el mutex, atómicamente.

5

Si no tiene C++ 11, pero tiene un sistema que admita los hilos POSIX, puede usar una variable de condición. Hay otras opciones, pero una variable de condición puede ser la más directa dada la forma en que describió su problema.

Una variable de condición pthread se utiliza junto con un mutex. El truco con la variable de condición es que esperar en ella hace que se libere el mutex adquirido, hasta que la llamada de espera regrese, momento en el cual el mutex ha sido adquirido nuevamente.La secuencia es:

  • mutex adquirir
  • mientras predicado no es cierto
    • espera en estado variable
  • hacer el trabajo en la sección crítica
  • si predicado es verdadero
    • condición de señal variable
  • liberación mutex

El paso de la señal se utiliza en caso de múltiples hilos están entrando en la misma sección crítica superior.

Si un subproceso diferente puede acceder al mismo mutex para modificar el estado que afecta a PREDICATE, ese subproceso debe verificar para ver si alguien necesita ser señalado.

  • adquirir mutex
  • hacer obras en la sección crítica
  • si predicado es verdadero
    • condición de señal variables
  • liberación de exclusión mutua

Los comandos POSIX de interés son :

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

Uso de semáforo para la señalización. Ejemplo (aplicación salida limpia) como a continuación:

Declare en la cabecera

static sem_t semPrepareExit;   //declaration 

en el origen (hilo principal);

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

En origen, (spawn-thread);

... 
sem_post(&semPrepareExit); 

Ahora, tan pronto como señalice en el semáforo usando "sem_post". El hilo principal recibirá la señal en el nodo/punto de espera, y continuará, hacia adelante.

0

intentar algo como esto:

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 
} 

// por lo finde que esperar a continuación, llamar al método WaitForEvent

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

// esto es como un evento podría ser señalado:

cndSignalEvent.notify_one(); 
Cuestiones relacionadas