【问题标题】:Is there an easy way to implement AutoResetEvent in C++0x?有没有在 C++0x 中实现 AutoResetEvent 的简单方法?
【发布时间】:2011-12-16 18:33:41
【问题描述】:

我知道我之前问过这个问题:What is the C++ equivalent for AutoResetEvent under Linux?

但是,我了解到在 C++0x 中,线程库变得更加简单,所以我想再次提出这个问题,有没有一种简单的方法可以在 C++0x 中实现 AutoResetEvent?

【问题讨论】:

    标签: c++ multithreading c++11 autoresetevent


    【解决方案1】:

    这里是accepted answer to your first question使用C++11工具的翻译:

    #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();
    }
    

    输出:

    Hello from the first thread
    Hello from other thread!
    

    更新

    tobsen 下面的cmets 中,AutoResetEvent 的语义是signal_.notify_all() 而不是signal_.notify_one()。我没有更改代码,因为accepted answer to the first question 使用了pthread_cond_signal 而不是pthread_cond_broadcast,我首先声明这是对该答案的忠实翻译。

    【讨论】:

    • 事实上,如果在 WaitOne 之前执行 Set 会产生死锁(如本答案中链接的问题的答案中所述)
    • 工作正常。感谢bool flag_how wait() works with std::unique_lock,不会出现死锁。
    • 您可能希望将 signal_.notify_one(); 更改为 signal_.notify_all(); 以反映 OP 所指的 AutoResetEvent 类的行为。
    • @tobsen:谢谢!我已经用这些信息更新了我的答案。
    • 是的。 flag_ 总是在互斥锁的保护下读写,因此不需要(也不应该)是原子的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 2012-02-08
    • 2020-09-18
    • 1970-01-01
    相关资源
    最近更新 更多