io_service的任务执行流程:
调用run方法,进入主loop;
判断公有队列是否为空,不为空则取出任务并执行,当任务数大于1时同时唤醒其他空闲线程;
任务执行结束,把各个线程的私有队里面的任务移动到公有任务队列里面。
触发reactor,linux下面一般是epoll,当有事件时,把相应的事件的任务放到私有队列里。
当队列为空时,把当前线程加到空闲线程队列里面,同时进入wait状态,等待其他线程的唤醒。
当用户调用post时,任务是直接投递到公有队列里面。
io_service.run():开始执行队列中的所有任务,直到任务执行完毕。
同步定时器:
#include <boost/thread.hpp> #include <boost/asio.hpp> #include <boost/date_time/posix_time/posix_time.hpp> int main() { boost::asio::io_service ios; // 所有asio程序都必须要有一个io_service对象 boost::asio::deadline_timer t(ios, boost::posix_time::seconds(2)); // 定时器 std::cout << t.expires_at() << std::endl; // 查看定时器终止的绝对时间 t.wait(); // 同步等待 std::cout << "hello!" << std::endl; return 0; }
异步定时器:
#include <boost/thread.hpp> #include <boost/asio.hpp> #include <boost/date_time/posix_time/posix_time.hpp> // error_code表示程序运行的错误 void call_back(const boost::system::error_code& e) { std::cout << "I am call_back." << std::endl; } int main() { boost::asio::io_service ios; // 所有asio程序都必须要有一个io_service对象 boost::asio::deadline_timer t(ios, boost::posix_time::seconds(2)); // 定时器 t.async_wait(call_back); // 异步等待,传入回调函数 std::cout << "我在定时器前面" << std::endl; ios.run(); // 等待异步操作完成,完成时io_service从操作系统获取执行结果,调用完成处理函数 return 0; }
异步定时器使用bind
#include <boost/thread.hpp> #include <boost/asio.hpp> #include <boost/date_time/posix_time/posix_time.hpp> class a_timer { private: int count, count_max; boost::function<void()> f; // 无参无返回的可调用用 boost::asio::deadline_timer t; // 定时器 public: template<typename F> a_timer(boost::asio::io_service &ios, int x, F func) : f(func), count_max(x), count(0), t(ios, boost::posix_time::millisec(500)) { t.async_wait(boost::bind(&a_timer::call_func, this, _1)); // 注册回调函数 } void call_func(const boost::system::error_code &e) { if (count > count_max) { return; } ++count; f(); t.expires_at(t.expires_at() + boost::posix_time::millisec(500)); t.async_wait(boost::bind(&a_timer::call_func, this, _1)); // 再次启动定时器 } }; void print1() { std::cout << "hello print1." << std::endl; } void print2() { std::cout << "hello print2." << std::endl; } int main() { boost::asio::io_service ios; a_timer t1(ios, 5, print1); a_timer t2(ios, 5, print2); ios.run(); // 异步等待调用结束 return 0; }