boost.asio系列——Timer
同步Timer
asio中提供的timer名為deadline_timer,它提供了超時計時的功能。首先以一個最簡單的同步Timer為例來演示如何使用它。
#include <iostream>
#include <boost/asio.hpp>
int main()
{
boost::asio::io_serviceio;
boost::asio::deadline_timertimer(io, boost::posix_time::seconds(3));
timer.wait();
std::cout << "Hello, world!\n";
return 0;
}
首先常見了一個io_service物件,它提供了IO排程功能,asio庫中的所有io操作都是基於它來執行的。然後建立了一個deadline_timer物件,它有兩個引數,一個是io_service物件,另一個是超時時間。
建立了timer後,就可以呼叫wait函式來阻塞等待至timer超時了,它還有一種可以指定錯誤碼的入參的過載形式,關於錯誤碼後面再介紹。
非同步Timer
同步timer雖然簡單,但由於其會阻塞,在實際的專案中並不常用,而往往使用的是非同步timer:指定一個回撥函式,計時器超時後執行回撥函式。asio中實現非同步timer比較簡單,示例如下:
void print(const boost::system::error_code& /*e*/)
{
std::cout << "Hello, world!\n";
}
int main()
{
boost::asio::io_service io;
boost::asio::deadline_timer timer(io, boost::posix_time::seconds(5));
timer.
io.run();
return 0;
}
和同步方式相比,它主要有兩點不同:
- 呼叫的是非阻塞函式async_wait,它的入參是一個回撥函式。
- 顯式呼叫io_service.run()函式驅動非同步IO排程。
取消Timer
Timer還有一種常用操作是取消Timer,基本方法如下:
- 呼叫timer的cancel函式取消timer
- timer取消後,回撥函式會立即執行,通過err_code可以感知到計時器是否已經被取消
void print(const boost::system::error_code& err)
{
if(
{
std::cout << "timer is canceled\n";
return;
}
std::cout << "Hello, world!\n";
}
int main()
{
boost::asio::io_service io;
boost::asio::deadline_timer timer(io, boost::posix_time::seconds(5));
timer.async_wait(&print);
boost::asio::deadline_timer timer2(io, boost::posix_time::seconds(2));
timer2.wait();
timer.cancel();
io.run();
return 0;
}
更改Timer超時時間
可以通過expires_from_now和expires_at兩個函式更改Timer的超時時間,如下示例就通過它實現一個週期計時器。
typedef std::function<void (const boost::system::error_code&)> timer_callback ;
void print(const boost::system::error_code&)
{
std::cout << "Hello, world!\n";
}
int main()
{
boost::asio::io_service io;
boost::asio::deadline_timer timer(io, boost::posix_time::seconds(1));
timer_callback callback = [&](const boost::system::error_code& err)
{
print(err);
timer.expires_at(timer.expires_at() + boost::posix_time::seconds(1));
timer.async_wait(callback);
};
timer.async_wait(callback);
io.run();
return 0;
}
PS:為了簡單,這兒用到了c++11的語法,不想用c++11語法可以參考boost文件的原始示例。