2016-09-19 28 views
7

Tôi đang cố gắng sử dụng một thread trong lớp, sau đó thread cần sử dụng condition_variable và biến điều kiện sẽ bị chặn cho đến khi vị từ được thay đổi thành true. Mã này trông như thế này:C++ condition_variable wait_for predicate trong lớp của tôi, std :: thread <unorolved overloaded type type> lỗi

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 
    } 

} ; 

Mã này vào biên soạn ném một lỗi nói:

chưa được giải quyết quá tải loại chức năng trong dòng “wait_for”.

Sau đó, tôi cố gắng sửa đổi nó để:

if(cv.wait_for(lck,std::chrono::milliseconds(3000),&myThreadClass::myPredicate)) 

Nhưng vẫn còn một lỗi.

+2

'if (cv.wait_for (lck, std :: chrono :: mili giây (3000), [this] {return myPredicate();}))' – ildjarn

+0

Sử dụng vị từ sai. Đó là cách không thể sử dụng biến vị ngữ. –

Trả lời

4

Vị ngữ cần phải được gọi mà không có bất kỳ ngữ cảnh nào. Bạn đang cố gắng gọi điều này trên một thành viên lớp không tĩnh, yêu cầu một đối tượng mà trên đó hoạt động.

Bạn có thể sử dụng một hàm lambda để nắm bắt hoàn cảnh của đối tượng và quấn gọi hàm vào một loại phù hợp:

const std::chrono::milliseconds timeout(3000); 
if(cv.wait_for(lck, timeout, [this]{ return myPredicate(); })) 
    // ... 

Nếu bạn chỉ tạo myPredicate vì biến điều kiện, bạn có thể làm đi với nó và chỉ cần sử dụng này:

if(cv.wait_for(lck, timeout, [this]{ return bFlag; })) 
2

có, trong thực tế, cách tốt nhất để làm điều này là ..

auto myPredicate = [this]{ return bFlag; } 

và sau đó sử dụng

if (cv.wait_for(lck, std::chrono::milliseconds(3000), myPredicate)) 

Bằng cách này bạn có thể loại bỏ phương pháp myPrediate.

4

Chức năng thành viên (con trỏ đến a) là biến vị ngữ không phù hợp, vì nó yêu cầu đối tượng được gọi, vì vậy bạn sẽ cần một trình bao bọc để kết nối hàm thành viên với đối tượng và làm cho nó có thể gọi được chỉ với hai giá trị để so sánh.

Trong C++ 11, bạn có thể gắn một hàm thành viên cho một đối tượng:

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 
} 
}; 

bạn có thể sử dụng placeholders trong ràng buộc.

Hoặc bạn có thể sử dụng hàm lambda.

Các vấn đề liên quan