2012-11-26 30 views
0

我的應用程序(C++,Windows)正在與外部設備進行通信。如果設備在一段時間後沒有應答,我想重置一個狀態變量。使用C++超時後重置變量

我最初的做法是

auto timer = boost::asio::deadline_timer(io_svc); 

timer.expires_from_now(boost::posix_time::seconds(10)); 
timer.async_wait(boost::bind(&Class::CurrRequestTimeout, this, boost::asio::placeholders::error)); 

io_svc.poll(); 

和超時功能

void Class::CurrRequestTimeout(const boost::system::error_code & ec) 
{ 
    if (ec) 
    { 
     // this timeout was canceled 
     return; 
    } 
    ResetStatusVariable(); 
} 

這應該是非阻塞的,這就是爲什麼我選擇的民意調查()而不是run()的(看到here) 。但是,使用poll()超時方法永遠不會被調用。使用run()它工作得很好,但是這會阻止執行。

+0

應該調用超時方法的代碼在哪裏?如果你沒有粘貼它,請做。如果沒有這樣的代碼,那麼你的問題。 –

+0

async_wait()應在超時過期或取消後調用超時方法。至少這是我的理解http://www.boost.org/doc/libs/1_48_0/doc/html/boost_asio/reference/basic_deadline_timer/async_wait.html – Simon

+1

如果這是正確的,它會怎麼做?沒有其他線索,至少不是你告訴我們的。 'async_wait'現在不能調用這個函數,因爲它還沒有結束。那麼這怎麼可能呢? –

回答

2

poll函數僅運行準備在該時刻運行的處理程序。由於計時器尚未超時,因此現在無法運行該處理程序。你問它不要阻止。那麼你期望它做什麼?

如果您的代碼是線程安全的,則創建另一個可以在run中阻塞的線程。如果沒有,那麼這個線程必須回來並稍後致電poll給處理程序一個運行的機會。

一個忠告:如果你創建一個或多個線程run,你需要確保始終有至少一個事件來等待,或線程將無法等待處理。 boost::asio::io_service::work就是爲了這個目的。見this question

+0

我試圖從那個異步的例子中得出我的解決方案:http://www.boost.org/doc/libs/1_48_0/ doc/html/boost_asio/reference/deadline_timer.html#boost_asio.reference.deadline_timer.examples我認爲async_wait()運行該處理程序 – Simon

+1

否。async_wait函數無法運行處理程序,因爲它立即返回並且處理程序isn'尚未準備好運行。無論代碼如何運行,處理程序都必須是一些運行十秒鐘的代碼。 –

+0

在我的代碼中找到了一個解決方案,將'run()'放入一個單獨的線程(已經存在)中。再次感謝您的澄清。 – Simon

0

如果您在超時之前調用poll,則沒有任何操作(但),因爲io_service poll將在沒有任何操作的情況下返回。在等待超時或您的外部設備通信時,您想要做什麼?你可以運行一個循環,等待外部設備通信,輪詢io_service對象和檢查超時標誌:

while (!checkForExternalDevicesCommunication()) 
{ 
    io_svc.poll(); 
    if (statusVariableHasTimeout()) 
    throw CommunicationTimeoutException(); 

    doSomethingInTheMeanTime(); 
    std::this_thread::sleep(some_time); 
} 

或實現與外部設備的通信以異步方式,Boost.Asio的風格和讓其在同一個io_service上運行。

+0

我假設deadline_timer已經爲我創建了一個線程(請參閱我對上述問題的評論)。感謝您的澄清。 – Simon

+0

這完全擊敗了截止日期計時器的邏輯。 –

+0

@DavidSchwartz謹慎地闡述? –