2013-10-11 38 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