0

我有一个自定义类“sau_timer”的代码:

sau_timer::sau_timer(int secs, timerparam f, vector<string> params) : strnd(io), 
    t(io, boost::posix_time::seconds(secs))
{
    assert(secs > 0);
    this->f = f;
    this->params = params;
    t.async_wait(strnd.wrap(boost::bind(&sau_timer::exec, this, _1)));
    boost::thread thrd(boost::bind(&boost::asio::io_service::run, &io));
    io.run();
}

void sau_timer::exec(const boost::system::error_code&) {
    (f)(params);
}

我想要这样当我创建一个 sau_timer 对象时,计时器将启动,但允许程序继续执行。例如,这是 main():

int main(int argc, char* argv[])
{
    vector<string> args(1);
    args[0] = "Hello!";
    sau_timer timer_test(3, sau_prompt, args);
    args[0] = "First!";
    sau_prompt(args);
    timer_test.thrd.join();
    return 0;
}

我的意图是创建 timer_test,在调用 sau_prompt("Hello!") 之前启动一个等待三秒的计时器,但将首先调用 sau_prompt("First!")。此时,在 First 之前的提示符中显示 Hello,表示计时器正在暂停整个程序三秒钟,然后才允许它继续。我希望计时器在后台运行。

我究竟做错了什么?代码编译...

谢谢你。

4

2 回答 2

6

您在 sau_timer 中调用“io.run()” - 这实质上是告诉 asio 反应器在可能的情况下处理任何/所有挂起的异步事件。

您应该在设置事件后调用 run 或 post,这是它通常的完成方式。查看 asio 文档中的示例。

#include <iostream>
#include <asio.hpp>

#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/date_time.hpp>
#include <boost/thread.hpp>


类 event_timer
{
上市:

   event_timer(asio::io_service& io_service,
               常量 std::size_t& tid,
               const std::size_t& 间隔 = 5)
   : io_service_(io_service),
     timer_(io_service),
     tid_(tid),
     间隔_(间隔),
     tick_count_(0),
     total_diff_(0)
   {
   }

   无效的开始()
   {
      timer_.cancel();
      启动定时器();
   }

   无效停止()
   {
      timer_.cancel();
   }

   void set_interval(const std::size_t& 毫秒)
   {
      间隔_ = 毫秒;
   }

私人的:

   内联无效initial_timer()
   {
      如果(间隔_)
      {
         timer_.expires_from_now(boost::posix_time::milliseconds(interval_));
         timer_.async_wait(
            boost::bind(&event_timer::handle_timer_event,this,
               asio::placeholders::error));
         before_ = boost::posix_time::microsec_clock::universal_time();
      }
   }

   内联 void handle_timer_event(const asio::error_code& 错误)
   {
      if (!error && interval_)
      {
         after_ = boost::posix_time::microsec_clock::universal_time();
         boost::posix_time::time_duration 持续时间 = after_ - before_;
         total_diff_ += std::abs(interval_ - duration.total_milliseconds());
         ++tick_count_;
         如果 (tick_count_ < 200)
            启动定时器();
         别的
            std::cout << "Timer["<< tid_ <<"]\tTick["<< tick_count_ <<"] 平均差异:" << total_diff_ / (1.0 * tick_count_) << std::endl;
      }
   }

   asio::io_service& io_service_;
   std::size_t tid_;
   std::size_t 间隔_;
   std::size_t tick_count_;
   asio::deadline_timer timer_;
   boost::posix_time::ptime before_;
   boost::posix_time::ptime after_;
   std::size_t total_diff_;
};

主函数()
{

   std::cout << "定时器测试" << std::endl;

   asio::io_service io_service;

   尝试
   {
      常量 std::size_t et_cnt = 1000;
      std::vector<event_timer*> et_lst;

      for(无符号整数 i = 0; i < et_cnt; ++i)
      {
         et_lst.push_back(new event_timer(io_service,i,10));
      }

      for(unsigned int i = 0; i < et_cnt;)
      {
         et_lst[i++]->start();
      }

      std::size_t 线程池大小 = 100;

      //创建一个线程池来运行所有的io_services。
      std::vector<boost::shared_ptr<boost::thread> > 线程;
      for (std::size_t i = 0; i < thread_pool_size; ++i)
      {
         boost::shared_ptr<boost::thread> 线程(新的 boost::thread(boost::bind(&asio::io_service::run, &io_service)));
         线程.push_back(线程);
      }

      // 等待池中的所有线程退出。
      for (std::size_t i = 0; i <threads.size(); ++i)
         线程[i]->join();
      for(unsigned int i = 0; i < et_cnt; 删除 et_lst[i++]);

   }
   捕获(标准::异常& e)
   {
      std::cout << "异常:" << e.what() << std::endl;
      返回 1;
   }

   返回0;
}
于 2009-08-27T16:19:43.880 回答
0

考虑到 namespace 和 boost 1.69 版本,应该做三处修改:

  1. 变成#include <asio.hpp>_#include <boost/asio.hpp>
  2. 添加:using namespace boost; using namespace boost:asio;
  3. 变成inline void handle_timer_event(const asio::error_code& error)_void handle_timer_event(const boost::system::error_code& error)
于 2018-12-15T15:32:31.723 回答