socket连接中需要判断超时
所以这几天看了看boost中计时器的文档和示例
一共有五个例子 从简单的同步等待到异步调用超时处理
先看第一个例子
1 // timer1.cpp: 定义控制台应用程序的入口点。 2 // 3 4 #include "stdafx.h" 5 #include <iostream> 6 #include <boost/asio.hpp> 7 #include <boost/date_time/posix_time/posix_time.hpp> 8 9 void print() { 10 std::cout << "Hello world" << std::endl; 11 } 12 13 int main() 14 { 15 boost::asio::io_service io; 16 17 boost::asio::deadline_timer t(io,boost::posix_time::seconds(5)); 18 t.wait(); 19 20 print(); 21 22 return 0; 23 }
几行代码 简单的声明计时器 等待五秒后继续执行
但是代码有一个问题就是 等待时间内 流程是卡死的
所以加以改进就是例子2 更改为异步等待
1 // timer2.cpp: 定义控制台应用程序的入口点。 2 // 3 4 #include "stdafx.h" 5 #include <iostream> 6 #include <boost/asio.hpp> 7 #include <boost/date_time/posix_time/posix_time.hpp> 8 9 void print(const boost::system::error_code&) { 10 std::cerr << "Hello world!" << std::endl; 11 } 12 13 14 int main() 15 { 16 boost::asio::io_service io; 17 boost::asio::deadline_timer t(io,boost::posix_time::seconds(5)); 18 t.async_wait(&print); 19 for (int i = 0; i < 3; i++) { 20 std::cout << "wait" << std::endl; 21 } 22 io.run(); 23 24 return 0; 25 }
例子3又添加了一个内容
异步等待函数中 再次设置异步等待时间和超时异步调用的回调函数
一共5次 由于传入的是计数count变量的指针 所以计数变量会累加
当累加到5 则不再继续
代码如下:
1 // timer3.cpp: 定义控制台应用程序的入口点。 2 // 3 #include <iostream> 4 #include <boost/asio.hpp> 5 #include <boost/bind.hpp> 6 #include <boost/date_time/posix_time/posix_time.hpp> 7 8 void print(const boost::system::error_code& /*e*/, 9 boost::asio::deadline_timer* t, int* count) 10 { 11 if (*count < 5) 12 { 13 std::cout << *count << std::endl; 14 ++(*count); 15 16 t->expires_at(t->expires_at() + boost::posix_time::seconds(1)); 17 t->async_wait(boost::bind(print, 18 boost::asio::placeholders::error, t, count)); 19 } 20 } 21 22 int main() 23 { 24 boost::asio::io_service io; 25 26 int count = 0; 27 boost::asio::deadline_timer t(io, boost::posix_time::seconds(1)); 28 t.async_wait(boost::bind(print, 29 boost::asio::placeholders::error, &t, &count)); 30 31 io.run(); 32 33 std::cout << "Final count is " << count << std::endl; 34 35 return 0; 36 }
例子4同例子3 不同之处在于 以类的形式封装了超时异步回调函数以及timer
1 // timer4.cpp: 定义控制台应用程序的入口点。 2 // 3 #include <iostream> 4 #include <boost/asio.hpp> 5 #include <boost/bind.hpp> 6 #include <boost/date_time/posix_time/posix_time.hpp> 7 8 class printer 9 { 10 public: 11 printer(boost::asio::io_service& io) 12 : timer_(io, boost::posix_time::seconds(1)), 13 count_(0) 14 { 15 timer_.async_wait(boost::bind(&printer::print, this)); 16 } 17 18 ~printer() 19 { 20 std::cout << "Final count is " << count_ << std::endl; 21 } 22 23 void print() 24 { 25 if (count_ < 5) 26 { 27 std::cout << count_ << std::endl; 28 ++count_; 29 30 timer_.expires_at(timer_.expires_at() + boost::posix_time::seconds(1)); 31 timer_.async_wait(boost::bind(&printer::print, this)); 32 } 33 } 34 35 private: 36 boost::asio::deadline_timer timer_; 37 int count_; 38 }; 39 40 int main() 41 { 42 boost::asio::io_service io; 43 printer p(io); 44 io.run(); 45 46 return 0; 47 }
例子5开启了两个timer分别在不同线程中运行
基本上阅读没有任何问题
但是实际编写中要深入了解 asio::io_service::strand 和 多线程运行ioser.run()
这两点需要注意 可以尝试不适用strand_.wrap
运行代码比对代码运行结果进行理解
代码如下
1 #include <iostream> 2 #include <boost/asio.hpp> 3 #include <boost/thread/thread.hpp> 4 #include <boost/bind.hpp> 5 #include <boost/date_time/posix_time/posix_time.hpp> 6 7 class printer 8 { 9 public: 10 printer(boost::asio::io_service& io) 11 : strand_(io), 12 timer1_(io, boost::posix_time::seconds(1)), 13 timer2_(io, boost::posix_time::seconds(1)), 14 count_(0) 15 { 16 timer1_.async_wait(strand_.wrap(boost::bind(&printer::print1, this))); 17 timer2_.async_wait(strand_.wrap(boost::bind(&printer::print2, this))); 18 } 19 20 ~printer() 21 { 22 std::cout << "Final count is " << count_ << std::endl; 23 } 24 25 void print1() 26 { 27 if (count_ < 10) 28 { 29 std::cout << "Timer 1: " << count_ << std::endl; 30 ++count_; 31 32 timer1_.expires_at(timer1_.expires_at() + boost::posix_time::seconds(1)); 33 timer1_.async_wait(strand_.wrap(boost::bind(&printer::print1, this))); 34 } 35 } 36 37 void print2() 38 { 39 if (count_ < 10) 40 { 41 std::cout << "Timer 2: " << count_ << std::endl; 42 ++count_; 43 44 timer2_.expires_at(timer2_.expires_at() + boost::posix_time::seconds(1)); 45 timer2_.async_wait(strand_.wrap(boost::bind(&printer::print2, this))); 46 } 47 } 48 49 private: 50 boost::asio::io_service::strand strand_; 51 boost::asio::deadline_timer timer1_; 52 boost::asio::deadline_timer timer2_; 53 int count_; 54 }; 55 56 int main() 57 { 58 boost::asio::io_service io; 59 printer p(io); 60 boost::thread t(boost::bind(&boost::asio::io_service::run, &io)); 61 io.run(); 62 t.join(); 63 64 return 0; 65 }