boost :: asio асинхронный таймер как прерывание - PullRequest
1 голос
/ 24 ноября 2011

Насколько я понимаю, я должен иметь возможность использовать асинхронный таймер boost: asio для запуска обратного вызова каждые n миллисекунд, пока моя программа делает что-то еще, не нуждаясь в потоках. Это предположение верно?

Я собрал следующую тестовую программу, которая просто печатает сообщения обработчика и никогда не печатает значения rand (). Я хочу видеть, как все числа с плавающей запятой прокручиваются вниз по экрану, а затем каждые 250 мс должно появляться сообщение обработчика.

Вот код:

#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 ]

2 голосов
/ 20 марта 2013

Как отметил Джон Цвинк, блоки 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();
   }
2 голосов
/ 24 ноября 2011

Это:

io_service.run();

Является ли блокирующий вызов.Это правда, что вы можете иметь несколько вещей, происходящих асинхронно в одном потоке, используя ASIO, но вы не можете запустить ASIO в том же потоке, что и код, который не интегрирован с ASIO.Это классическая модель, управляемая событиями, где вся работа выполняется в ответ на некоторые уведомления о готовности (в вашем случае таймеры).

Попробуйте переместить ваш векторный / рандовый код в функцию и передать эту функциюio_service :: post (), который затем запустит этот код в контексте его метода run ().Затем, когда вы вызываете run (), произойдут обе вещи (хотя и не по-настоящему одновременно, поскольку для этого потребуются потоки).

...