2009-09-30 8 views
12

Je me demande s'il y a un boost de ManualResetEvent? Fondamentalement, je voudrais une implémentation multi-plateforme ... Ou, quelqu'un pourrait-il m'aider à imiter la fonctionnalité de ManualResetEvent en utilisant Boost :: thread? Merci les garsBoost équivalent de ManualResetEvent?

+0

Quelles fonctions d'événement souhaitez-vous émuler? – curiousguy

Répondre

12

Il est assez facile d'écrire un événement de réinitialisation manuelle lorsque vous avez des mutex et des variables de condition.

Ce dont vous aurez besoin est un champ qui indique si votre événement de réinitialisation est signalé ou non. L'accès au champ devra être surveillé par un mutex - cela inclut à la fois la configuration/la réinitialisation de votre événement ainsi que la vérification pour voir si elle est signalée. Lorsque vous attendez votre événement, s'il n'est pas actuellement signalé, vous devez attendre une variable de condition jusqu'à ce qu'elle soit signalée. Enfin, dans votre code qui définit l'événement, vous souhaiterez notifier la variable de condition pour réveiller toute personne en attente de votre événement.

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

Je pense que vous devrez utiliser 'boost :: condition_variable_any' pour que cela fonctionne. Voir: http://stackoverflow.com/questions/8758353/whats-the-difference-between-stdcondition-variable-and-stdcondition-variable – Nick

+0

De plus, la méthode condition_variable_any :: wait doit recevoir le mutex en paramètre, pas la garde de serrure. – Oliver

+0

Hmm, je reçois: erreur C2664 'boost :: vide condition_variable :: attente (boost :: unique_lock &)': ne peut pas convertir le paramètre 1 de 'boost :: lock_guard ' à 'boost :: unique_lock &' J'utilise condition_variable_any, j'obtiens une autre erreur à l'intérieur de condition_variable à propos de la méthode unlock() qui n'existe pas. – Alexander

1

IIRC, ManualResetEvent s existent pour permettre à plusieurs threads d'attendre sur un objet, et un thread pour se réveiller à la fois lorsque l'objet est signalé. La partie "réinitialisation manuelle" provient du fait que le système ne réinitialise pas automatiquement l'événement après qu'il a réveillé un thread; vous faites cela à la place.

Cela semble très similaire à condition variables:

Le modèle d'utilisation général est qu'un fil verrouille un mutex puis appelle wait sur une instance de condition_variable ou condition_variable_any. Lorsque le thread est réveillé à partir de l'attente, il vérifie si la condition appropriée est maintenant vraie et continue si c'est le cas. Si la condition n'est pas vraie, le thread appelle ensuite wait pour reprendre l'attente.

+0

J'ai simplement un thread d'écriture qui doit toujours écrire et ne jamais être bloqué, alors que j'ai un thread de lecture qui ne peut lire que lorsque l'écrivain n'écrit pas ... si cela a du sens. Merci – Polaris878

+0

Je dirais que votre conception est logique. –