1. 程式人生 > >boost::asio名字空間中的deadline_time類:定時器

boost::asio名字空間中的deadline_time類:定時器

定時器是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();
}