2013-10-11 41 views
3

我想等待一段時間的條件。 我讀了助推文檔,似乎最好使用帶謂詞的函數wait_for,如here所述。boost :: condition_variable - 使用wait_for與謂詞

不幸的是,這個例子對我來說並不是很有用。我應該如何編寫謂詞?我試着寫上面報道的代碼,但在Visual Studio編譯器抱怨:c:\boost\boost\thread\win32\condition_variable.hpp(394): error C2064: term does not evaluate to a function taking 0 arguments

這是代碼的一部分:

class MyClass{ 

    boost::mutex mutex; 
    boost::condition_variable myCondition; 
    //... 
    void foo(); 
    bool myPredicate(); 
} 


void MyClass::foo(){ 

    boost::unique_lock<boost::mutex> lock(mutex); 

    boost::chrono::microseconds period(25000); 
    // ... 
    boost::chrono::system_clock::time_point wakeUpTime = boost::chrono::system_clock::now() + period; 
    if(myCondition.wait_until(lock,wakeUpTime,MyClass::myPredicate) == true){/...} 

} 

bool MyClass::myPredicate(){ 

    if(...) 
    return true; 
    else 
    return true; 
} 

什麼用wait_for與謂語的正確方法是什麼?

回答

7

建議使用帶有謂詞的wait函數,因爲與手寫循環相比,它們的出錯率更低。一個手工編寫循環可能如下:

for (;;) { 
    if (myPredicate()) { 
     // ... [successful case] 
     break; 
    } else if (myCondition.wait_until(lock, wakeUpTime) == boost::cv_status::timeout) { 
     // ... [timeout case] 
     break; 
    } // else: continue loop [spurious wakeup] 
} 

如果傳遞一個謂詞的wait功能,這可能是一個功能性的東西,可以不帶任何參數調用,並返回一個類型,可用作bool。例如,你可以使用一個static成員函數用於這一目的:

struct Foobar { 
    static bool isFoobar(); 
}; 

myCondition.wait_until(lock, wakeUpTime, Foobar::isFoobar); 

您不能直接傳遞一個非靜態成員函數,因爲它只能與一個對象被調用。但是,您可以使用函數對象來代替:

struct MyPredicateWrapper { 
    MyClass* _ptr; 
    explicit MyPredicateWrapper(MyClass* ptr) : _ptr(ptr) { } 
    bool operator()() const { return _ptr->myPredicate(); } 
}; 

myCondition.wait_until(lock, wakeUpTime, MyPredicateWrapper(this)); 

您可以boost::bind基本相同的事情:如果您使用的是C++ 11

myCondition.wait_until(lock, wakeUpTime, boost::bind(&MyClass::myPredicate, this)); 

而且,你還可以使用lambda函數

myCondition.wait_until(lock, wakeUpTime, [this] { return myPredicate(); }); 
+0

感謝這個完整的雁,所以基本上使用的最後兩個提出的方法之一,讓我來調用函數'比如說myPredicate()'在CURREN t對象。那是對的嗎?這允許我通過使用'myClass'中定義的變量來評估謂詞。 – Maverik

+1

除了第一個('Foobar'),它們都可以訪問'myClass'中定義的實例變量。我建議使用_anonymous function_。它可以讓你將謂詞的部分內容聯繫在一起,並將屬於一起的東西彙集在一起​​。但是,我不確定此功能是否已被Visual Studio支持。 – nosid

+0

是的,Visual Studio 2012支持它,代碼編譯。你知道有沒有辦法測試它?我的意思是,謂詞用於在虛假虛弱情況下避免錯誤。有沒有辦法模擬虛假的虛弱? – Maverik