简体   繁体   English

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

[英]boost::asio asynchronous timer as an interrupt

As I understand it, I should be able to use a boost:asio asynchronous timer to trigger a callback every n milliseconds whilst my program is doing something else without needing threads. 据我所知,我应该能够使用boost:asio异步计时器每n毫秒触发一次回调,同时我的程序在不需要线程的情况下执行其他操作。 Is that assumption correct ? 这个假设是否正确?

I put together the following test program which just prints the handler messages and never prints the rand() values. 我把以下测试程序放在一起,它只打印处理程序消息,而不打印rand()值。 What I want is to see all the floating point numbers scroll down the screen, then every 250ms a handler message should appear in amongst them. 我想要的是看到所有浮点数在屏幕上向下滚动,然后每隔250ms就会出现一个处理程序消息。

Here is the code : 这是代码:

#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;
}

As John Zwinck mentioned, io_service::run() blocks - it's a main asio loop that dispatches completion handlers. 正如John Zwinck所提到的, io_service::run()阻塞 - 它是一个主要的asio循环,它调度完成处理程序。 However, instead of calling run , you can "manually" process the io_service queue by interleaving io_service::poll_one with your loop: 但是,您可以通过将io_service::poll_one与循环交错来“手动”处理io_service队列,而不是调用run

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

This: 这个:

io_service.run();

Is a blocking call. 是一个阻止电话。 It's true that you can have multiple things happening asynchronously in one thread using ASIO, but you cannot have ASIO running in the same thread as code which is not integrated with ASIO. 确实,您可以使用ASIO在一个线程中异步发生多个事情,但是您不能让ASIO在与未与ASIO集成的代码相同的线程中运行。 This is a classic event-driven model, where all the work gets done in response to some readiness notification (timers, in your case). 这是一个典型的事件驱动模型,所有工作都是在响应一些准备就绪通知(在您的情况下为计时器)时完成的。

Try moving your vector/rand code to a function and passing that function to io_service::post(), which will then run that code within the context of its run() method. 尝试将vector / rand代码移动到函数并将该函数传递给io_service :: post(),然后在其run()方法的上下文中运行该代码。 Then when you invoke run(), both things will happen (though not truly concurrently, as that would require threads). 然后当你调用run()时,两件事都会发生(尽管不是真正的并发,因为这需要线程)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM