c++自定义定时器
我们公司最近被qt公司盯上说侵权,现在在去qt化,本博文的定时器可以代替QTimer。这个代码可用,不卡GUI,缺点是每创建一个对象就创建一个子线程。
·
我们公司最近被qt公司盯上说侵权,现在在去qt化,本博文的定时器可以代替QTimer。
#ifndef TIMEERCPP_H
#define TIMEERCPP_H
#include <thread>
#include <atomic>
class Timer
{
public:
void setInterval(int interval);
~Timer();
void stop();
void start();
private:
void run();
std::atomic<bool> active{false};
int interval{1000};
std::thread workerThread;
};
#endif
#include "timercpp.h"
#include <iostream>
#include <thread>
void Timer::setInterval(int interval)
{
this->interval = interval;
}
Timer::~Timer()
{
if(active.load())
{
stop();
}
}
void Timer::stop()
{
active = false;
if(workerThread.joinable())
{
workerThread.join();
}
}
void Timer::start()
{
if(active.load())
{
stop();
}
active = true;
workerThread = std::thread(&Timer::run, this);
}
void Timer::run()
{
std::cout<<"run"<<std::endl;
while(active.load())
{
std::this_thread::sleep_for(std::chrono::milliseconds(interval));
if(!active.load())
return;
std::cout<<"xxx"<<std::endl;
}
}
这个代码可用,不卡GUI,缺点是每创建一个对象就创建一个子线程。
下面这个代码则进行了优化,使用一个子线程统一处理:
#ifndef TIMEERCPP_H
#define TIMEERCPP_H
#include <thread>
#include <atomic>
#include <list>
#include <mutex>
#include <chrono>
class Timer
{
public:
Timer();
~Timer();
void updateTime(long long currentTime_millisec);
void setInterval(int newInterval);
private:
long long millisec_since_epoch_currentTime;
int interval{1000};
int GC{0};
};
class TimerEventManager
{
public:
static TimerEventManager* getInstance();
~TimerEventManager();
void addTimer(Timer * timer);
void removeTimer(Timer * timer);
void start();
void stop();
private:
void run();
std::list<Timer*> list;
std::atomic<bool> active{false};
std::thread workerThread;
std::mutex mutex;
};
#endif
TimerEventManager *TimerEventManager::getInstance()
{
static TimerEventManager manager;
return &manager;
}
TimerEventManager::~TimerEventManager()
{
active = false;
if(workerThread.joinable())
{
workerThread.join();
}
}
void TimerEventManager::addTimer(Timer *timer)
{
std::lock_guard<std::mutex> lock(mutex);
list.push_back(timer);
}
void TimerEventManager::removeTimer(Timer *timer)
{
std::lock_guard<std::mutex> lock(mutex);
list.remove(timer);
}
void TimerEventManager::start()
{
active.store(true);
workerThread = std::thread(&TimerEventManager::run,this);
}
void TimerEventManager::stop()
{
active.store(false);
if (workerThread.joinable())
{
workerThread.join();
}
}
void TimerEventManager::run()
{
while(active.load())
{
std::this_thread::sleep_for(std::chrono::milliseconds(50));
if (!active.load())
return;
auto currentTime_millisec = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
std::lock_guard<std::mutex> lock(mutex);
for (auto& timer : list)
{
timer->updateTime(currentTime_millisec);
}
}
}
Timer::Timer()
{
//获取时间点相对于 epoch(通常是 1970 年 1 月 1 日 00:00:00 UTC)的持续时间的函数。
millisec_since_epoch_currentTime = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
TimerEventManager::getInstance()->addTimer(this);
}
Timer::~Timer()
{
TimerEventManager::getInstance()->removeTimer(this);
}
void Timer::updateTime(long long currentTime_millisec)
{
int t = (currentTime_millisec - millisec_since_epoch_currentTime) / interval;
if(t > GC)
{
GC = t;
std::cout<<"超时 interval = "<<interval<<std::endl;
}
}
void Timer::setInterval(int newInterval)
{
interval = newInterval;
}
更多推荐
已为社区贡献12条内容
所有评论(0)