Search code examples
c++multithreadingc++11autoresetevent

Is there an easy way to implement AutoResetEvent in C++0x?


I understand I've asked this question before: What is the C++ equivalent for AutoResetEvent under Linux?

However, I'm learning that in C++0x, the threading library are made much simpler, so I want to pose this question out again, is there an easy way to implement AutoResetEvent in C++0x?


Solution

  • Here is a translation of the accepted answer to your first question to use C++11 tools:

    #include <mutex>
    #include <condition_variable>
    #include <thread>
    #include <stdio.h>
    
    class AutoResetEvent
    {
      public:
      explicit AutoResetEvent(bool initial = false);
    
      void Set();
      void Reset();
    
      bool WaitOne();
    
      private:
      AutoResetEvent(const AutoResetEvent&);
      AutoResetEvent& operator=(const AutoResetEvent&); // non-copyable
      bool flag_;
      std::mutex protect_;
      std::condition_variable signal_;
    };
    
    AutoResetEvent::AutoResetEvent(bool initial)
    : flag_(initial)
    {
    }
    
    void AutoResetEvent::Set()
    {
      std::lock_guard<std::mutex> _(protect_);
      flag_ = true;
      signal_.notify_one();
    }
    
    void AutoResetEvent::Reset()
    {
      std::lock_guard<std::mutex> _(protect_);
      flag_ = false;
    }
    
    bool AutoResetEvent::WaitOne()
    {
      std::unique_lock<std::mutex> lk(protect_);
      while( !flag_ ) // prevent spurious wakeups from doing harm
        signal_.wait(lk);
      flag_ = false; // waiting resets the flag
      return true;
    }
    
    
    AutoResetEvent event;
    
    void otherthread()
    {
      event.WaitOne();
      printf("Hello from other thread!\n");
    }
    
    
    int main()
    {
      std::thread h(otherthread);
      printf("Hello from the first thread\n");
      event.Set();
    
      h.join();
    }
    

    Output:

    Hello from the first thread
    Hello from other thread!
    

    Update

    In the comments below tobsen notes that AutoResetEvent has the semantics of signal_.notify_all() instead of signal_.notify_one(). I haven't changed the code because the accepted answer to the first question used pthread_cond_signal as opposed to pthread_cond_broadcast and I am leading with the statement that this is a faithful translation of that answer.