boostを使用したdeadline_timerは非同期タイマを実現する

4217 ワード

概要
最近、仕事でタイマーを使う必要があります.boostのdeadlineを見ます.timerはタイマーを実現できるので、直接ATimerクラスにカプセル化し、使いやすく、ATimerには以下の利点があります.
  • は、ナノ秒、ミリ秒、秒、分、時間のタイミングをサポートすることができる.
  • はタイマーをいつでも停止することができます.
  • は、シングルコールをサポートします.
  • deadlineを使っているのでtimerなので、タイミングが正確です.

  • ATimerとQtのQTimerの使用方法は似ていますが、似たようなTimerクラスがなければ、最も原始的な方法を使用すると、私たちのコードはこのようになる可能性があります.
    m_timerThread = std::thread([this]
    {
        while (!m_bThreadStoped)
        {
            ++m_sleepCount;
            Sleep(SLEEP_DURATION_TIME);
    
            if (m_sleepCount == m_sleepAllCount)
            {
                m_sleepCount = 0;
                doSomeThing();
            }
        }
    });

    QTimerを使うと、書くとこうなります.
    QTimer *timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(update()));
    timer->start(1000);

    ATimerの使用を見てみましょう.
    ATimer<> t;
    t.bind([]{ std::cout << "Hello C++" << std::endl; });
    t.start(1000);

    上記の例から、QTimerとATimerの使用は非常に便利であることがわかります.次に、ATimerの具体的な実装を見てみましょう.
    // ATimer.hpp
    #ifndef _ATIMER_H
    #define _ATIMER_H
    
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    template
    class ATimer
    {
    public:
        ATimer() : m_timer(m_ios, Duration(0)), m_isSingleShot(false) {}
        ~ATimer()
        {
            stop();
        }
    
        void start(unsigned int duration)
        {
            if (m_ios.stopped())
            {
                return;
            }
    
            m_isActive = true;
            m_duration = duration;
            m_timer.expires_at(m_timer.expires_at() + Duration(m_duration));
            m_func = [this]
            {
                m_timer.async_wait([this](const boost::system::error_code&)
                {
                    for (auto& func : m_funcVec)
                    {
                        func();
                    }
    
                    if (!m_isSingleShot)
                    {
                        m_timer.expires_at(m_timer.expires_at() + Duration(m_duration));
                        m_func();
                    }
                });
            };
    
            m_func();
            m_thread = std::thread([this]{ m_ios.run(); });
        }
    
        void stop()
        {
            m_ios.stop();
            if (m_thread.joinable())
            {
                m_thread.join();
            }
            m_isActive = false;
        }
    
        void bind(const std::function& func)
        {
            m_funcVec.emplace_back(func);
        }
    
        void setSingleShot(bool isSingleShot)
        {
            m_isSingleShot = isSingleShot; 
        }
    
        bool isSingleShot() const
        {
            return m_isSingleShot;
        }
    
        bool isActive() const
        {
            return m_isActive;
        }
    
    private:
        boost::asio::io_service m_ios;
        boost::asio::deadline_timer m_timer;
        std::function m_func = nullptr;
        std::vector<:function>> m_funcVec;
        std::thread m_thread;
        unsigned int m_duration = 0;
        std::atomic m_isSingleShot;
        bool m_isActive = false;
    };
    
    #endif
    
    

    ATimerの具体的な使用例を次に示します.
    // main.cpp
    #include 
    #include "ATimer.hpp"
    
    void test()
    {
        std::cout << "Timer thread id: " << std::this_thread::get_id() << std::endl;
    }
    
    int main()
    {
        std::cout << "Main thread id: " << std::this_thread::get_id() << std::endl;
    
        ATimer<:posix_time::minutes> t0;
        t0.setSingleShot(true);//     
        t0.bind(test);
        t0.start(1);//        
    
        ATimer<> t;//         
        t.bind(test);
        t.bind([]{ std::cout << "Hello C++" << std::endl; });
        t.start(1000);// 1000ms    
    
        std::cin.get();
        t0.stop();
        t.stop();
        std::cout << "Tiemr stop" << std::endl;
    
        std::cin.get();
        std::cout << "Process end" << std::endl;
    
        return 0;
    }
    
    

    この例のgithubアドレス:https://github.com/chxuan/samples/tree/master/ATimer
    転載先:https://www.cnblogs.com/highway-9/p/5737421.html