0

我的应用程序(C++、Windows)正在与外部设备通信。如果设备在一段时间后没有响应,我想重置一个状态变量。

我最初的方法是

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

这应该是非阻塞的,这就是我选择 poll() 而不是 run() 的原因(见这里)。但是,使用 poll() 永远不会调用 timeout 方法。使用 run() 它可以正常工作,但这会阻止执行。

4

2 回答 2

2

poll函数仅运行准备在该时刻运行的处理程序。由于计时器尚未超时,因此它现在无法运行该处理程序。你要求它不要阻止。那么你希望它做什么呢?

如果您的代码是线程安全的,请创建另一个可以阻塞的线程run。如果不是,则该线程必须返回并poll稍后调用以使处理程序有机会运行。

一个警告:如果您确实创建了一个或多个run线程,则需要确保始终至少有一个事件要等待,否则线程将无法等待处理程序。boost::asio::io_service::work只是为了这个目的。看到这个问题

于 2012-11-26T10:17:06.167 回答
0

如果您在超时之前调用 poll,则(还)没有任何事情可做,因为 io_service 轮询将在没有任何操作的情况下返回。在等待超时或来自外部设备的通信时,您想做什么?您可以运行一个循环,等待外部设备通信,轮询 io_service 并检查超时标志:

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

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

或者以异步方式实现与外部设备的通信,Boost.Asio 风格,让它在同一个 io_service 上运行。

于 2012-11-26T10:26:30.643 回答