我试图在我的类中使用一个线程,然后线程需要使用condition_variable
,条件变量将被阻塞,直到谓词变为true
。代码如下所示:
class myThreadClass{
bool bFlag;
thread t ;
mutex mtx;
condition_variable cv;
bool myPredicate(){
return bFlag;
}
int myThreadFunction(int arg){
while(true){
unique_lock<mutex> lck(mtx);
if(cv.wait_for(lck,std::chrono::milliseconds(3000),myPredicate)) //something wrong?
cout<<"print something...1"<<endl
else
cout<<"print something...2"<<endl
}
}
void createThread(){
t = thread(&myThreadClass::myThreadFunction,this,10);//this is ok
}
} ;
编译时的这段代码会抛出错误说:
“wait_for”行中未解决的重载函数类型。
然后我尝试将其修改为:
if(cv.wait_for(lck,std::chrono::milliseconds(3000),&myThreadClass::myPredicate))
但仍有错误。
答案 0 :(得分:4)
谓词需要在没有任何上下文的情况下进行调用。您试图在非静态类成员上调用它,这需要一个操作对象。
您可以使用lambda函数捕获对象的上下文并将函数调用包装为合适的类型:
const std::chrono::milliseconds timeout( 3000 );
if( cv.wait_for( lck, timeout, [this]{ return myPredicate(); } ) )
// ...
如果您因为条件变量而只创建了myPredicate
,那么您可以取消它并使用它:
if( cv.wait_for( lck, timeout, [this]{ return bFlag; } ) )
答案 1 :(得分:4)
(指向一个)成员函数作为谓词的指针是不合适的,因为它需要一个对象被调用,所以你需要一个包装器来绑定成员函数到一个对象,并使其只有两个要比较的值可调用。
在C ++ 11中,您可以将成员函数绑定到对象:
class myThreadClass{
bool bFlag;
thread t ;
mutex mtx;
condition_variable cv;
bool myPredicate(){
return bFlag;
}
int myThreadFunction(int arg){
while(true){
unique_lock<mutex> lck(mtx);
if(cv.wait_for(lck,std::chrono::milliseconds(3000),std::bind(&myThreadClass::myPredicate,this))) //something wrong?
cout<<"print something...1"<<endl;
else
cout<<"print something...2"<<endl;
}
}
void createThread(){
t = thread(&myThreadClass::myThreadFunction,this,10);//this is ok
}
};
您可以在bind中使用占位符。
或者你可以使用lambda函数。
答案 2 :(得分:2)
是的,实际上最好的办法是......
auto myPredicate = [this]{ return bFlag; }
然后使用
if (cv.wait_for(lck, std::chrono::milliseconds(3000), myPredicate))
这样您就可以取消myPrediate
方法。