2009-09-30 10 views
12

Me pregunto si hay un aumento equivalente a ManualResetEvent? Básicamente, me gustaría una implementación multiplataforma ... O, ¿podría alguien ayudarme a imitar la funcionalidad de ManualResetEvent usando Boost :: thread? Gracias chicosAumentar el equivalente de ManualResetEvent?

+0

¿Qué funciones de evento desea emular? – curiousguy

Respuesta

12

Es bastante fácil escribir un evento de reinicio manual cuando tiene mutexes y variables de condición.

Lo que necesitará es un campo que representa si su evento de reinicio está señalizado o no. El acceso al campo deberá estar protegido por un mutex; esto incluye tanto configurar/restablecer el evento como verificar si está señalizado.

Cuando está esperando su evento, si no está señalizado actualmente, querrá esperar una variable de condición hasta que se señalice. Finalmente, en su código que establece el evento, querrá notificar a la variable de condición para despertar a cualquiera que esté esperando su evento.

class manual_reset_event 
{ 
public: 
    manual_reset_event(bool signaled = false) 
     : signaled_(signaled) 
    { 
    } 

    void set() 
    { 
     { 
      boost::lock_guard<boost::mutex> lock(m_); 
      signaled_ = true; 
     } 

     // Notify all because until the event is manually 
     // reset, all waiters should be able to see event signalling 
     cv_.notify_all(); 
    } 

    void unset() 
    { 
     boost::lock_guard<boost::mutex> lock(m_); 
     signaled_ = false; 
    } 


    void wait() 
    { 
     boost::lock_guard<boost::mutex> lock(m_); 
     while (!signaled_) 
     { 
      cv_.wait(lock); 
     } 
    } 

private: 
    boost::mutex m_; 
    boost::condition_variable cv_; 
    bool signaled_; 
}; 
+1

Creo que es posible que necesite usar 'boost :: condition_variable_any' para que esto funcione. Ver: http://stackoverflow.com/questions/8758353/whats-the-difference-between-stdcondition-variable-and-stdcondition-variable – Nick

+0

Además, el método condition_variable_any :: wait debe tener el mutex como parámetro, no el protector de seguridad. – Oliver

+0

Hmm, me sale: 'impulso vacío :: :: condition_variable espera (boost :: unique_lock Y)' error C2664: no se puede convertir el parámetro 1 de 'boost :: lock_guard ' a 'impulsar :: unique_lock &' Si utilizo condition_variable_any, aparece otro error dentro de condition_variable sobre el método de desbloqueo(). – Alexander

1

IIRC, ManualResetEvent s existen para permitir que varios subprocesos esperen en un objeto, y un subproceso para despertarse en el momento en que se señala el objeto. La parte de "reinicio manual" proviene del hecho de que el sistema no reinicia automáticamente el evento después de que despierta un hilo; lo haces en su lugar.

Esto suena muy similar a condition variables:

El patrón de uso general es que un hilo bloquea un mutex y luego llama wait en una instancia de condition_variable o condition_variable_any. Cuando el hilo se despierta de la espera, comprueba si la condición adecuada ahora es verdadera y continúa si es así. Si la condición no es verdadera, entonces el hilo vuelve a llamar al wait para reanudar la espera.

+0

Básicamente tengo un hilo de escritor que siempre debe escribir y nunca ser bloqueado, mientras que tengo un hilo de lectura que solo puede leer cuando el escritor no está escribiendo ... si eso tiene sentido. Gracias – Polaris878

+0

Diría que su diseño tiene sentido. –

Cuestiones relacionadas