timer 定时器实现

#ifndef L1_TIMER_H_
#define L1_TIMER_H_

#include <iostream>
#include <set>
#include <atomic>
#include <memory>
#include <mutex>  
#include <sstream>  
#include <string> 
#include <thread>
#include <functional>
#include <iomanip>



#include <shared_mutex>
#include <unordered_map> 

using namespace std;



class L1Timer 
{
public:
    using Callback = std::function<void(unsigned int)>;

    L1Timer(const std::string& name, Callback callback, unsigned int interval)
        : name_(name), callback_(callback), interval_(interval), running_(false) {}

    void start() 
    {
        //std::lock_guard<std::mutex> lock(mutex_);
        if (!running_) 
        {
            running_ = true;
            tp_ = std::chrono::steady_clock::now();// use other tp clock huimingf
            tp_sys_ = std::chrono::system_clock::now();
        }
    }

    void update(const std::string& name, Callback callback, unsigned int interval) 
    {
        name_ = name;
        callback_ = callback;
        interval_ = interval;
    }

    void stop() 
    {
        //std::lock_guard<std::mutex> lock(mutex_);
        running_ = false;
    }

    void dump(stringstream &oss) const 
    {
        std::stringstream ss;
        time_t t1 = std::chrono::system_clock::to_time_t(tp_sys_);
        ss  << std::put_time(localtime(&t1), "%Y-%m-%d %H:%M:%S");        
        oss << "timer[" << name_ << "]  start: " << ss.str() << " interval: " << interval_
            << " status:" << (running_ ? " running":" stopped") << std::endl;    
    }

    const std::string& getName() const 
    {
        return name_;
    }

    bool isRunning() const 
    {
        return running_;
    }

    unsigned int getInterval() const 
    {
        return interval_;
    }

    void executeCallback(unsigned int index) const 
    {
        if (callback_) 
        {
            callback_(index);
        }
    }

    std::chrono::steady_clock::time_point getStartTime()
    {
        return tp_;
    }

    unsigned int getTimeCountDown()
    {
        auto now = std::chrono::steady_clock::now();

        auto elapsed = std::chrono::duration_cast<std::chrono::seconds>(now - tp_);
        
        if (elapsed.count() < interval_)
        {
            return interval_ - elapsed.count();
        }
        else
        {
           return 0; 
        }    
    }

private:
    std::string name_;
    Callback callback_;
    unsigned int interval_;
    std::chrono::steady_clock::time_point tp_;
    std::chrono::system_clock::time_point tp_sys_;//use for dump
    //mutable std::mutex mutex_;
    std::atomic<bool> running_;
};


class L1TimerManager 
{
public:
    L1TimerManager();
    ~L1TimerManager();
    static shared_ptr<L1TimerManager> GetL1TimerManager();

    void createTimer(const unsigned int &index, const std::string& name, L1Timer::Callback callback, unsigned int interval);
    void updateTimer(const unsigned int &index, const std::string& name, L1Timer::Callback callback, unsigned int interval);
    void registerDefaultCallback(L1Timer::Callback callback);
    bool isTimerExisted(const unsigned int &index);
    unsigned int getTimeCountDown(const unsigned int &index);
    void startTimer(const unsigned int &index); 
    void stopTimer(const unsigned int &index);
    void removeTimer(const unsigned int &index); 
    void dumpTimers(stringstream &oss);
    void start(); 
    void stop();
    std::string timePoint2Str(std::chrono::system_clock::time_point tp_);
    
private:
    void timerLoop(); 
    
private:
    //std::vector<Timer> timers_;
    //std::unordered_map<unsigned int, std::shared_ptr<L1Timer>> timers_; 
    static shared_ptr<L1TimerManager> instance_;
    std::map<unsigned int, std::shared_ptr<L1Timer>> timers_; 
    std::shared_ptr<std::thread> timerThread_;
    std::atomic<bool> running_;
    mutable std::shared_mutex mutex_; // 用于同步对timers_的访问 
    L1Timer::Callback default_call_back;
};

#endif /* L1_TIMER_H_ */
#include <map>
#include <chrono>
#include <iomanip>
#include <sstream>  
#include <string> 

#include "l1_timer.h"

using namespace std;

shared_ptr<L1TimerManager> L1TimerManager::instance_ = nullptr;

L1TimerManager::L1TimerManager(): running_(false)
{

}

L1TimerManager::~L1TimerManager()
{
    stop();
}

shared_ptr<L1TimerManager> L1TimerManager::GetL1TimerManager()
{
    if(nullptr==instance_){
        //instance_ = new L1Util();
        instance_ = make_shared<L1TimerManager>();
    }

    return instance_;
}


void L1TimerManager::registerDefaultCallback(L1Timer::Callback callback)
{
    std::unique_lock<std::shared_mutex> lck(mutex_);
    default_call_back = callback;
}


bool L1TimerManager::isTimerExisted(const unsigned int &index)
{
    std::unique_lock<std::shared_mutex> lck(mutex_);
    
    if (timers_.find(index) != timers_.end()) 
    {  
        return true;
    }
    return false;
}


unsigned int L1TimerManager::getTimeCountDown(const unsigned int &index)
{
    std::unique_lock<std::shared_mutex> lck(mutex_);
    auto it = timers_.find(index); 
    
    if (it != timers_.end()) 
    {  
        return it->second->getTimeCountDown();
    }
    else
    {
        return 0;
    }
    
}

void L1TimerManager::createTimer(const unsigned int &index, const std::string& name, L1Timer::Callback callback, unsigned int interval) 
{
    std::unique_lock<std::shared_mutex> lck(mutex_);

    L1Timer::Callback act_callback = default_call_back;
    if (callback)
    {
        act_callback = callback;
    }
    else
    {
        //LOG("create Timer:" << index << " name " << name << " default call_back");
    }
    
    if (timers_.find(index) != timers_.end()) 
    {  
        //LOG("create Timer:" << index << " name " << name << "failed");
    }
    else
    {
        timers_[index] = std::make_shared<L1Timer>(name, act_callback, interval);
        //LOG("create Timer:" << index << " name " << name << " successfully");
    }    
}


void L1TimerManager::updateTimer(const unsigned int &index, const std::string& name, L1Timer::Callback callback, unsigned int interval)
{
    std::unique_lock<std::shared_mutex> lck(mutex_);

    L1Timer::Callback act_callback = default_call_back;

    if (callback)
    {
        act_callback = callback;
    }
    else
    {
       //LOG("update Timer:" << index << " name " << name << " default call_back");
    }
    
    auto it = timers_.find(index);
    if (it == timers_.end()) 
    { 
        //LOG("update Timer " << index << "failed");
    }
    else
    {
        it->second->update(name, act_callback, interval); 
        //LOG("update Timer:" << index << " name " << it->second->getName() << " successfully");
    }

}


void L1TimerManager::startTimer(const unsigned int &index) 
{  
    std::shared_lock<std::shared_mutex> lck(mutex_); 
    auto it = timers_.find(index);  
    if (it == timers_.end()) 
    {  
        //LOG("start Timer " << index << "failed");
    }
    else
    {
        it->second->start(); 
        //LOG("start Timer:" << index << " name " << it->second->getName() << " successfully");
    }
}  
  
void L1TimerManager::stopTimer(const unsigned int &index) 
{ 
    std::shared_lock<std::shared_mutex> lck(mutex_);  
    auto it = timers_.find(index);  
    if (it == timers_.end()) 
    {
        //LOG("stop Timer " << index << " name " << it->second->getName() << "failed");
    }
    else
    {
        it->second->stop();  
    }
}  
  
void L1TimerManager::removeTimer(const unsigned int &index) 
{   
    std::unique_lock<std::shared_mutex> lck(mutex_);
    auto it = timers_.find(index);  
    if (it == timers_.end()) 
    {
        //LOG("remove Timer " << index << " name " << it->second->getName() << "failed");
    }
    else
    { 
        //stopTimer(name);
        //LOG("remove Timer " << index << " name " << it->second->getName() << "successfully");
        it->second->stop();
        timers_.erase(it);
        
    }    
}
    
void L1TimerManager::dumpTimers(stringstream &oss)
{
    std::shared_lock<std::shared_mutex> lck(mutex_); 
    for(auto& kv:timers_){
            (kv.second)->dump(oss);
    }
}

void L1TimerManager::start() 
{
    if (!running_) 
    {
        running_ = true;
        timerThread_ = make_shared<std::thread>(&L1TimerManager::timerLoop, this);
        std::string name = "l1TestMon";
        pthread_setname_np(timerThread_->native_handle(), name.c_str());
    }
}

void L1TimerManager::stop() 
{
    if (running_) 
    {
        running_ = false;
        if (timerThread_)
        {
            timerThread_->join();
            //SWSS_LOG_INFO("Thread: l1TestMon stopped!");
        }
    }
}

std::string L1TimerManager::timePoint2Str(std::chrono::system_clock::time_point tp_)
{
    std::stringstream ss;
    time_t t1 = std::chrono::system_clock::to_time_t(tp_);
    ss << std::put_time(localtime(&t1), "%Y-%m-%d %H:%M:%S");
    //std::cout << "time: " << ss.str() << std::endl;
    return ss.str();
}


void L1TimerManager::timerLoop() 
{
    stringstream oss;
    while (running_) 
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(200)); // Adjust sleep time as needed
        oss.clear();
        oss.str("");
        std::shared_lock<std::shared_mutex> lck(mutex_); 
        for (auto&item : timers_) 
        {
            unsigned int index = item.first;
            std::shared_ptr<L1Timer> timer = item.second;
             
            if (timer->isRunning()) 
            {
                auto now = std::chrono::steady_clock::now();
                auto elapsed = std::chrono::duration_cast<std::chrono::seconds>(now - timer->getStartTime());
                if (elapsed.count() >= timer->getInterval()) 
                {
                    //std::cout << "current time: " << timePoint2Str(now) << std::endl;
                    timer->executeCallback(index);
                    timer->dump(oss); // Optional: Print timer status
                    //LOG("dump:" << oss.str());
                    //timer.start(); // Restart the timer
                    timer->stop();
                    
                }
            }
        }
        
    }
}

void TimerCallBackFunc(unsigned int lc_index)
{
    std::cout << lc_index << " Timer ticked!!!"  << std::endl;
    return;
}


L1TimerManager tm1;





int main() {

	std::stringstream oss;
    tm1.createTimer(1, "myTimer1", TimerCallBackFunc, 3);
    tm1.createTimer(2, "myTimer2", TimerCallBackFunc, 5);
    tm1.createTimer(3, "myTimer3", TimerCallBackFunc, 7);
    tm1.createTimer(4, "myTimer4", TimerCallBackFunc, 9);
    tm1.createTimer(5, "myTimer5", TimerCallBackFunc, 11);
    tm1.createTimer(6, "myTimer6", TimerCallBackFunc, 13);

    tm1.start();

    tm1.startTimer(1);
    tm1.startTimer(2);
    tm1.startTimer(3);
	tm1.startTimer(4);
    tm1.startTimer(5);
    tm1.startTimer(6);

    // Let the timers run for a while
    std::this_thread::sleep_for(std::chrono::seconds(20));
    tm1.dumpTimers(oss);
	std::cout << "dump:" << oss.str() << std::endl;
    tm1.stop();

    std::cout << "-----remove Timer ----" << std::endl;
    tm1.removeTimer(1);
    tm1.removeTimer(2);

    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值