2017-06-07 42 views
1

我想了解如何使用timed_wait。我發現只有幾個例子(herehere),並且在絕對時間調用它時遇到問題。下面的代碼是一個簡化的例子,實際上這一切都發生在一個類中,所以我認爲手動檢查我的謂詞會更容易,而不必使用一些綁定並將其傳遞給timed_wait爲什麼在絕對時間調用boost :: timed_wait塊時會永遠阻塞?

#include <boost/date_time/posix_time/posix_time.hpp> 
#include <boost/thread.hpp> 
#include <iostream> 

bool done = false; 
boost::mutex mutex; 
boost::thread waitingThread; 
boost::condition_variable cond; 

void wait(boost::posix_time::time_duration dt){ 
    boost::mutex::scoped_lock lock(mutex); 
    boost::system_time x = boost::posix_time::microsec_clock::local_time() + dt; 
    bool timedOut = false; 
    while((done == false) && (x > boost::posix_time::microsec_clock::local_time())) { 
     timedOut = ! cond.timed_wait(lock,x); 
    } 
    if (timedOut){ std::cout << "timeout\n"; } 
    else   { std::cout << "success\n"; } 
} 

void wait2(boost::posix_time::time_duration dt){ 
    boost::mutex::scoped_lock lock(mutex); 
    bool timedOut = ! cond.timed_wait(lock,dt); 
    if (timedOut){ std::cout << "timeout\n"; } 
    else   { std::cout << "success\n"; } 

} 

void test(){ 
    //boost::thread waiter = boost::thread(wait,boost::posix_time::milliseconds(50)); 
    boost::thread waiter = boost::thread(wait2,boost::posix_time::milliseconds(50)); 
    boost::this_thread::sleep(boost::posix_time::milliseconds(2000)); 
} 

第一個版本永遠阻塞,我不明白爲什麼。另一方面,第二個版本afaik會受到虛假喚醒的影響。正如我之前所說的,在實際的代碼,這一切都是一個類裏面的地方,所以,需要使用帶有謂詞的過載,我將不得不做一些像

cond.timed_wait(lock,dt, ?bind?(&Foo::isDone,this)); 

但後來我不是100%肯定,如果一個虛假喚醒將使timed_wait回報true(如果這是我的while (x > local_time())將是多餘的情況。

回答

3

使用boost::get_system_time() + dt,這是不是local_time() + dt基於UTC,這是時區調整,因爲wait_lock(...)使用boost::get_system_time()比較電流時間與目標絕對時間。

下面的例子說明了這個問題:

int main() { 
    std::cout << "System time: " 
       << boost::get_system_time() << std::endl; 
    std::cout << "Local time: " 
       << boost::posix_time::microsec_clock::local_time() << std::endl; 
} 

輸出:

System time: 2017-Jun-07 08:47:58.836677 
Local time: 2017-Jun-07 11:47:58.837003 

所以,你絕對時間爲基礎的wait()功能塊只是通過時區指定了幾個小時的偏移您的計算機,而不是永遠。

相關問題