條件變量condition_variable存在的一些問題

C++11中完善了信號量與條件變量(參見:C++11中線程及信號量與條件變量),但是condition_variable的一些實現是存在問題的,特別是在Windows下會很容易出現假喚醒的情形(VS2015的實現,在Win10下非常容易出現,而Win7下偶爾出現)。

爲避免此種假喚醒情形,需要使用帶Predicate參數的重載接口,以下是Event接口的模擬實現:

class XuEvent{  // No signal when init
public:
    void wait(){
        std::unique_lock<std::mutex> lker(m_mtx);
        m_bNotified = false;
        m_cv.wait(lker, [this] {return this->m_bNotified; });
    }

    bool wait(int nSec, int nMillSec=0){
        std::unique_lock<std::mutex> lker(m_mtx);
        m_bNotified = false;
        std::chrono::seconds secs(nSec);
        std::chrono::milliseconds mills(nMillSec);
        auto ret = m_cv.wait_for(lker, secs + mills, [this] {return this->m_bNotified; });
        //return (ret != std::cv_status::timeout);
        return ret;
    }

    void notifyOne(){
        m_bNotified = true;
        m_cv.notify_one();
    }
    void notifyAll(){
        m_bNotified = true;
        m_cv.notify_all();
    }

private:
    bool m_bNotified = false;
    std::mutex m_mtx;
    std::condition_variable m_cv;
};

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章