boost::asio名字空間中的deadline_time類:定時器
阿新 • • 發佈:2019-01-29
定時器是asio庫中最簡單的一個IO模型,提供等候時間終止的功能。
定時器功能的主要類是:deadline_timer
類,類摘要如下
使用定時器時的標頭檔案:
#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
using namespace boost::asio;
1. 同步定時器
//同步定時器的用法
void synchronously_timer_test()
{
std::cout << "wait for 5 seconds" << std::endl;
boost::asio::io_service ios; //所有asio程式必須有一個io_service物件
boost::asio::deadline_timer t(ios, boost::posix_time::seconds(15)); //定時器物件構造
std::cout << t.expires_at() << std::endl; //檢視終止的絕對時間
t.wait(); //同步等待,如果不等待,則直接往下執行
std::cout << "hello asio" << std::endl;
}
同步定時器和sleep()函式比較
1. thread庫中的sleep()使用互斥量和條件變數,線上程中等待。
2. asio則是呼叫了作業系統的非同步機制,如select、epoll等完成。
2. 非同步定時器
非同步定時器,增加了回撥函式,並使用io_service::run()和定時器的async_wait()方法。
回撥函式:asio庫要求回撥函式只能有一個引數,而且這個引數必須是const asio::error_code &
型別。(async_wait()接受的回撥函式型別是固定的)
例項:
//回撥函式
void printing(system::error_code& e)
{
std::cout << "asynchronously timer test: hello asio" << std::endl;
}
//非同步定時器的用法
void asynchronously_timer_test()
{
std::cout << "asychronously timer test begin" << std::endl;
boost::asio::io_service ios; //io_service物件
boost::asio::deadline_timer t(ios, boost::posix_time::seconds(2)); //定時器物件
t.async_wait(printing); //非同步等待,傳入回撥函式,立即返回
ios.run(); //非同步IO必須
}
非同步定時器區別於同步定時器:
1. async_wait()方法:通知 io_service 非同步地執行 IO 操作,並註冊回撥函式,用於在IO操作完成時由事件多路分離器分派返回值(error_code)呼叫。
2. 最後必須呼叫io_service的run()成員函式,它啟動前攝器的事件處理迴圈,阻塞等待所有的操作完成並分派事件。
如果不呼叫run(),那麼雖然操作被非同步執行了,但沒有一個等待它完成的機制,回撥函式將得不到執行機會。
3. 當定時器時間終止時,io_service將呼叫被註冊的printing()回撥函式,然後程式結束。
3. 非同步定時器使用bind
async_wait()接受的回撥函式型別是固定的,如果需要增減回撥函式的引數,必須使用bind庫來繫結引數以適配它的介面。
例項:
//帶引數的回撥函式
void printing(std::string &str)
{
std::cout << "asynchronously timer test: hello asio" << std::endl;
std::cout << str << std::endl;
}
//非同步定時器的用法
void asynchronously_timer_test()
{
std::cout << "asychronously timer test begin" << std::endl;
boost::asio::io_service ios;
boost::asio::deadline_timer t(ios, boost::posix_time::seconds(2));
std::string str("hello bind");
t.async_wait(boost::bind(printing,boost::ref(str))); //繫結引數,返回一個可用回撥函式。
ios.run();
}
4. 多執行緒中使用同步定時器 例項
//多執行緒中使用同步定時器
class printer
{
public:
printer(boost::asio::io_service &io):m_strand(io),
m_timer1(io,boost::posix_time::seconds(1)),
m_timer2(io,boost::posix_time::seconds(1)),
m_count(0){
m_timer1.async_wait(boost::bind(&printer::print1, this));
m_timer2.async_wait(boost::bind(&printer::print2, this));
}
void print1(){
boost::mutex::scoped_lock lock(mu);
if (m_count < 10){
std::cout << "timer1:" << m_count << std::endl;
++m_count;
m_timer1.expires_at(m_timer1.expires_at() + boost::posix_time::seconds(1));
m_timer1.async_wait(boost::bind(&printer::print1, this));
}
}
void print2(){
boost::mutex::scoped_lock lock(mu);
if (m_count < 10){
std::cout << "timer2:" << m_count << std::endl;
++m_count;
m_timer2.expires_at(m_timer2.expires_at() + boost::posix_time::seconds(1));
m_timer2.async_wait(boost::bind(&printer::print2, this));
}
}
private:
boost::asio::io_service::strand m_strand;
boost::asio::deadline_timer m_timer1;
boost::asio::deadline_timer m_timer2;
int m_count;
boost::mutex mu;
};
void synchronously_in_multithread_test()
{
std::cout << "synchronously_in_multithread_test begin: " << std::endl;
boost::asio::io_service io;
printer p(io);
boost::thread t(boost::bind(&boost::asio::io_service::run, &io));
io.run();
t.join();
}