我有自定义类'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!”)。此时,Hello显示在First之前的提示中,表示计时器正在暂停整个程序三秒钟,然后才允许它继续。我希望计时器在后台运行。
我做错了什么?代码编译......
谢谢。
答案 0 :(得分:6)
你在sau_timer中调用“io.run()” - 这实际上告诉asio reactor如果可以的话处理任何/所有挂起的异步事件。
您应该在设置事件后调用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> class event_timer { public: event_timer(asio::io_service& io_service, const std::size_t& tid, const std::size_t& interval = 5) : io_service_(io_service), timer_(io_service), tid_(tid), interval_(interval), tick_count_(0), total_diff_(0) { } void start() { timer_.cancel(); initiate_timer(); } void stop() { timer_.cancel(); } void set_interval(const std::size_t& milliseconds) { interval_ = milliseconds; } private: inline void initiate_timer() { if (interval_) { 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(); } } inline void handle_timer_event(const asio::error_code& error) { if (!error && interval_) { after_ = boost::posix_time::microsec_clock::universal_time(); boost::posix_time::time_duration duration = after_ - before_; total_diff_ += std::abs(interval_ - duration.total_milliseconds()); ++tick_count_; if (tick_count_ < 200) initiate_timer(); else std::cout << "Timer["<< tid_ <<"]\tTick["<< tick_count_ <<"] Average Diff: " << total_diff_ / (1.0 * tick_count_) << std::endl; } } asio::io_service& io_service_; std::size_t tid_; std::size_t interval_; std::size_t tick_count_; asio::deadline_timer timer_; boost::posix_time::ptime before_; boost::posix_time::ptime after_; std::size_t total_diff_; }; int main() { std::cout << "Timer Test" << std::endl; asio::io_service io_service; try { const std::size_t et_cnt = 1000; std::vector<event_timer*> et_lst; for(unsigned int 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 thread_pool_size = 100; //Create a pool of threads to run all of the io_services. std::vector<boost::shared_ptr<boost::thread> > threads; for (std::size_t i = 0; i < thread_pool_size; ++i) { boost::shared_ptr<boost::thread> thread(new boost::thread(boost::bind(&asio::io_service::run, &io_service))); threads.push_back(thread); } // Wait for all threads in the pool to exit. for (std::size_t i = 0; i < threads.size(); ++i) threads[i]->join(); for(unsigned int i = 0; i < et_cnt; delete et_lst[i++]); } catch(std::exception& e) { std::cout << "Exception: " << e.what() << std::endl; return 1; } return 0; }
答案 1 :(得分:0)
考虑名称空间和boost版本1.69,应进行三处修改:
#include <asio.hpp>
更改为#include <boost/asio.hpp>
using namespace boost; using namespace boost:asio;
inline void handle_timer_event(const asio::error_code& error)
更改为void handle_timer_event(const boost::system::error_code& error)