首页 > 代码库 > BOOST ASIO 学习专贴
BOOST ASIO 学习专贴
1.同步使用Timer
本便使用了boost::asio::deadline_timer,这个timer有两种状态:过期和不过期。wait函数调用一个过期的timer直接返回。
int _tmain(int argc, _TCHAR* argv[]){ boost::asio::io_service io; boost::asio::deadline_timer t(io,boost::posix_time::seconds(5)); t.wait(); std::cout<<"wait finished!"<<std::endl; return 0;}
2.异步使用Timer
下在演示了使用deadline_timer的asyn_wati函数实现异步等待。但要注意的一点是异步等待必须要调用io.run才可以。而且必须在io.run函数执行之前调用asyn_wait,否则io.run会立即返回,因为他没有可以做的事。这说明io.run必须至少有一个等待的,否则它会直接返回。asio函数保证回调函数执行和io.run所在的线程一样!
//异步Timervoid print(const boost::system::error_code & ){ std::cout<<"Wait Finished"<<std::endl;}int _tmain(int argc, _TCHAR* argv[]){ boost::asio::io_service io; boost::asio::deadline_timer t(io,boost::posix_time::seconds(5)); t.async_wait(&print); io.run(); return 0;}
3.为回调函数绑定参数
这个例子一个是说明异步Timer的可持续性问题,也就是在回调中设置Time的超时时间。另一个说明回调函数参数的绑定 。但是实际发现我官的代码没有发生那个重复回调的效果。原因是我只是调用了expire_at而没有调用再次等待函数async_wait。这让我更加明白expires_at这个函数相当于下次触发的时间。而async_wait提交一个等待申请。
async_wait提交一次,回调函数执行一次,而expire_at设定下次回调函数调用的时间。
#include <boost/bind.hpp>void Print(const boost::system::error_code & , boost::asio::deadline_timer * t,int * count){ if(*count < 5) { std::cout<<*count<<std::endl; ++(*count); t->expires_at(t->expires_at() + boost::posix_time::seconds(1)); t->async_wait(boost::bind(Print,boost::asio::placeholders::error,t,count)); }}int _tmain(int argc, _TCHAR* argv[]){ boost::asio::io_service io; int count = 0; boost::asio::deadline_timer t(io,boost::posix_time::seconds(1)); t.async_wait(boost::bind(Print,boost::asio::placeholders::error,&t,&count)); io.run(); return 0;}
4.类成员做为timer的回调函数
这个例子主要演示了,如何绑定一个类成员函数作为一个回调
class Print{public: Print(boost::asio::io_service & io) :timer_(io,boost::posix_time::seconds(1)),count_(0) { timer_.async_wait(boost::bind(&Print::print,this)); } ~Print() { std::cout<<"finnal count is "<<count_<<std::endl; } void print() { if(count_ < 5) { std::cout<<count_<<std::endl; ++count_; timer_.expires_at(timer_.expires_at() + boost::posix_time::seconds(1)); timer_.async_wait(boost::bind(&Print::print,this)); } }protected: boost::asio::deadline_timer timer_; int count_;};int _tmain(int argc, _TCHAR* argv[]){ boost::asio::io_service io; Print p(io); io.run(); return 0;}
4.在多线程程序中的同步回调
先前的例子通过io_service.run和同步回调在同一个线程内,正如你所知的那样,asio保证回调函数只能被在io_service.run()所在的线程调用 。因此,只有在一个线程内调用io_service::run保证回调函数不会并发执行。这样在服务器程序中有两个局限性:
1.当回调函数执行时间比较长时响应太慢
2.没有起到多处理器的优势
如果你注意到这个局限性,一个可供选择的方案是创建一个线程池去调用io_service.run()函数,这样实现的回调的并发,我们需要去同步一个共享变量。
下面的例子使用到了An boost::asio::strand ,他保证这些回调函数通过strans派遣,它可以允许一个回调函数在另一个回调函数执行之前完成。
#include <boost/thread/thread.hpp>class printer{public: printer(boost::asio::io_service & io) :strand_(io), timer1_(io,boost::posix_time::seconds(1)), timer2_(io,boost::posix_time::seconds(1)), count_(0) { timer1_.async_wait(strand_.wrap(boost::bind(&printer::print1,this))); timer2_.async_wait(strand_.wrap(boost::bind(&printer::print2,this))); } void print1() { if(count_ < 10) { std::cout<<"Timer 1:"<<count_<<std::endl; ++count_; timer1_.expires_at(timer1_.expires_at() + boost::posix_time::seconds(1)); timer1_.async_wait(strand_.wrap(boost::bind(&printer::print1,this))); } } void print2() { if(count_ < 10) { std::cout<<"Timer 2:"<<count_<<std::endl; ++count_; timer2_.expires_at(timer2_.expires_at() + boost::posix_time::seconds(1)); timer2_.async_wait(strand_.wrap(boost::bind(&printer::print2,this))); } }private: boost::asio::io_service::strand strand_; boost::asio::deadline_timer timer1_; boost::asio::deadline_timer timer2_; int count_;};int _tmain(int argc, _TCHAR* argv[]){ boost::asio::io_service io; printer p(io); boost::thread t(boost::bind(&boost::asio::io_service::run,&io)); io.run(); t.join(); return 0;}
下面有时间研究一下 boost::asio::strand的用法
BOOST ASIO 学习专贴