代码之家  ›  专栏  ›  技术社区  ›  DigitalZebra

与ManualResetEvent等量的增压?

  •  12
  • DigitalZebra  · 技术社区  · 15 年前

    我想知道是否有相当于manualResetEvent的增压?基本上,我想要一个跨平台的实现…或者,有人能帮我用boost::thread模拟manualResetevent的功能吗?谢谢大家

    2 回复  |  直到 13 年前
        1
  •  12
  •   Nick    13 年前

    当您有互斥锁和条件变量时,很容易编写手动重置事件。

    您需要的是一个字段,该字段表示重置事件是否已发出信号。对该字段的访问需要由互斥保护-这包括设置/重置事件以及检查是否有信号。

    当您等待事件时,如果当前没有发出信号,您将希望等待一个条件变量,直到发出信号。最后,在设置事件的代码中,您将希望通知条件变量以唤醒等待事件的任何人。

    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_;
    };
    
        2
  •  1
  •   Max Lybbert    15 年前

    IIRC ManualResetEvent 存在允许多个线程在一个对象上等待,并且一个线程在对象发出信号时被唤醒。“手动重置”部分来自这样一个事实,即系统在唤醒线程后不会自动重置事件;您可以这样做。

    这听起来很像 condition variables 以下内容:

    一般的使用模式是一个线程锁定互斥体,然后调用 wait 以…为例 condition_variable condition_variable_any . 当线程从等待中被唤醒时,它将检查适当的条件现在是否为真,如果为真,则继续。如果条件不是真的,那么线程将调用 等待 再次恢复等待。