boost :: asio异步计时器作为中断

时间:2011-11-24 14:48:07

标签: c++ boost timer boost-asio interrupt

据我了解,我应该能够使用boost:asio异步计时器每隔n毫秒触发一次回调,同时我的程序在不需要线程的情况下执行其他操作。这个假设是否正确?

我将以下测试程序放在一起,该程序只打印处理程序消息并且从不打印rand()值。我想要的是看到所有浮点数在屏幕上向下滚动,然后每隔250ms就会出现一个处理程序消息。

以下是代码:

#include <iostream>
#include <vector>
#include <cstdlib>

#include <boost/asio.hpp>
#include <boost/date_time.hpp>
#include <boost/thread.hpp>

boost::asio::io_service io_service;
boost::posix_time::time_duration interval(boost::posix_time::milliseconds(250));
boost::asio::deadline_timer timer(io_service,interval);

void handler(const boost::system::error_code& error);

void timer_init() {
   timer.expires_at(timer.expires_at()+interval);
   timer.async_wait(handler);
}

void handler(const boost::system::error_code& error) {
   static long count=0;
   std::cout << "in handler " << count++ << std::endl;
   std::cout.flush();
   timer_init();
}

int main(int argc, char **argv) {
   timer.async_wait(handler);
   io_service.run();

   std::vector<double> vec;
   for (long i=0; i<1000000000; i++) {
      double x=std::rand();
      std::cout << x << std::endl;
      std::cout.flush();
      vec.push_back(x);
   }
   return 0;
}

2 个答案:

答案 0 :(得分:2)

此:

io_service.run();

是阻止通话。确实,您可以使用ASIO在一个线程中异步发生多个事情,但是您不能让ASIO在与未与ASIO集成的代码相同的线程中运行。这是一个典型的事件驱动模型,所有工作都是在响应一些准备就绪通知(在您的情况下为计时器)时完成的。

尝试将vector / rand代码移动到函数并将该函数传递给io_service :: post(),然后在其run()方法的上下文中运行该代码。然后当你调用run()时,两件事都会发生(虽然不是真正的并发,因为这需要线程)。

答案 1 :(得分:2)

正如John Zwinck所提到的,io_service::run()阻塞 - 它是一个主asio循环,用于调度完成处理程序。但是,您可以通过将run与您的循环交错来“手动”处理io_service队列,而不是调用io_service::poll_one

for (long i=0; i<1000000000; i++) {
      double x=std::rand();
      std::cout << x << std::endl;
      std::cout.flush();
      vec.push_back(x);
      io_service.poll_one();
   }