我想等待一段时间的条件。
我阅读了boost文档,似乎最好将函数wait_for
与谓词一起使用,如here所述。
不幸的是,这个例子对我来说并不是很有用。我该如何编写谓词?我试着编写上面报告的代码但是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
与谓词一起使用的正确方法是什么?
答案 0 :(得分: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
基本相同的事情:
myCondition.wait_until(lock, wakeUpTime, boost::bind(&MyClass::myPredicate, this));
如果你使用的是C ++ 11,你也可以使用 lambda函数:
myCondition.wait_until(lock, wakeUpTime, [this] { return myPredicate(); });