2009-09-30 6 views
12

Mi chiedo se esiste un equivalente di boost di ManualResetEvent? Fondamentalmente, mi piacerebbe un'implementazione multipiattaforma ... Oppure qualcuno potrebbe aiutarmi a simulare le funzionalità di ManualResetEvent usando Boost :: thread? Grazie ragazziBoost equivalente di ManualResetEvent?

+0

Quali funzioni di evento si desidera emulare? – curiousguy

risposta

12

È facile scrivere un evento di ripristino manuale quando si hanno mutex e variabili di condizione.

Ciò di cui avrete bisogno è un campo che rappresenta se il vostro evento di reset è segnalato o meno. L'accesso al campo dovrà essere sorvegliato da un mutex - questo include sia l'impostazione/reset del tuo evento, sia il controllo per vedere se è segnalato.

Quando si è in attesa dell'evento, se non è attualmente segnalato, è necessario attendere una variabile di condizione finché non viene segnalato. Infine, nel tuo codice che imposta l'evento, ti consigliamo di notificare la variabile di condizione per svegliare chiunque sia in attesa del tuo 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

Penso che potrebbe essere necessario utilizzare 'boost :: condition_variable_any' perché funzioni. Vedi: http://stackoverflow.com/questions/8758353/whats-the-difference-between-stdcondition-variable-and-stdcondition-variable – Nick

+0

Inoltre, il metodo condition_variable_any :: wait deve avere come parametro il mutex, non la guardia della serratura. – Oliver

+0

Hmm, ottengo: 'spinta vuoto :: :: condition_variable attesa (boost :: unique_lock &)' errore C2664: non può convertire il parametro 1 da 'boost :: lock_guard ' a 'boost :: unique_lock &' Io uso condition_variable_any, ottengo un altro errore dentro condition_variable sul metodo unlock() non esiste. – Alexander

1

IIRC, ManualResetEvent s esistono per consentire a più thread di attendere su un oggetto e un thread per essere risvegliati in un momento in cui viene segnalato l'oggetto. La parte "reset manuale" deriva dal fatto che il sistema non ripristina automaticamente l'evento dopo che ha attivato un thread; lo fai invece.

Questo suona molto simile a condition variables:

Lo schema generale di utilizzo è che un thread blocca un mutex e poi chiama wait in un'istanza di condition_variable o condition_variable_any. Quando il thread viene riattivato dall'attesa, controlla se la condizione appropriata è vera e continua in tal caso. Se la condizione non è vera, quindi il thread chiama nuovamente wait per riprendere l'attesa.

+0

Fondamentalmente ho solo un thread writer che deve sempre scrivere e non essere mai bloccato, mentre ho un thread reader che può solo leggere quando lo scrittore non sta scrivendo ... se questo ha senso. Grazie – Polaris878

+0

Direi che il tuo progetto ha un senso. –