2012-11-26 29 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谨慎地阐述? –