#ifndef CBT_TIMER_H
#define CBT_TIMER_H
/***********************************************
*CBT_Timer
*description:定时器类
*
*created by y.y
* 2023/9/26
*回调函数定义:void timerCallBack(){...}
*用法说明:
*例1:CBT_Timer timer1(1000, timerCallBack);
*例2:CBT_Timer timer2;
* timer2.InitTimer(1000, timerCallBack);
*定时器时间间隔参数单位:毫秒
***********************************************/
#include <thread>
#include <functional>
#include <chrono>
#include <future>
#include <mutex>
#include <atomic>
#include <condition_variable>
#include <assert.h>
#include <unistd.h>
class CBT_Timer;
typedef std::shared_ptr<CBT_Timer> CBT_TimerPtr;
class CBT_Timer
{
friend class F;
public:
CBT_Timer();
~CBT_Timer(void);
//带参数的构造函数
template<class F, class... Args>
CBT_Timer(uint32_t dwTimeout, F&& f, Args&&... args)
{
m_bExit = false;
m_funCallback = std::bind(std::forward<F>(f), std::forward<Args>(args)...);
_InitTimer(dwTimeout);
}
//如果使用默认构造函数定义的示例 可以手动初始化 不允许重复调用
template<class F, class... Args>
bool InitTimer(uint32_t dwTimeout, F&& f, Args&&... args)
{
//assert(m_funCallback == nullptr);
if (m_funCallback != nullptr)
return false;
m_funCallback = std::bind(std::forward<F>(f), std::forward<Args>(args)...);
_InitTimer(dwTimeout);
return true;
}
//阻塞事件,会等所有的回调都完成后再退出
//如果在回调内部调用,会立即返回
void StopTimer();
//触发一次事件 异步返回
//必然触发的回调,哪怕调用了StopTimer也会把Set过的次数都回调一遍再退出
void SetTimerEvent();
private:
void _InitTimer(uint32_t nTimeout);
private:
CBT_Timer(const CBT_Timer&) = delete;
CBT_Timer& operator=(const CBT_Timer&) = delete;
std::mutex m_mtx;
std::condition_variable m_Condition;
std::future<int> m_loopTask; //线程任务
std::thread::id m_loopThreadID; //线程ID
std::function<void()> m_funCallback; //回调函数
bool m_bExit; //退出标记
std::atomic<int> m_nManual;
};
#endif // CBT_TIMER_H
/***********************************************
*CBT_Timer
*description:定时器类
*
*created by y.y
* 2023/9/26
*回调函数定义:void timerCallBack(){...}
*用法说明:
*例1:CBT_Timer timer1(1000, timerCallBack);
*例2:CBT_Timer timer2;
* timer2.InitTimer(1000, timerCallBack);
*定时器时间间隔参数单位:毫秒
***********************************************/
#include "cbt_timer.h"
CBT_Timer::CBT_Timer()
{
m_bExit = false;
}
CBT_Timer::~CBT_Timer()
{
StopTimer();
}
void CBT_Timer::_InitTimer(uint32_t nTimeout)
{
m_nManual = 0;
m_loopTask = std::async(std::launch::async, [this, nTimeout]()->int
{
//时间线程启动
m_loopThreadID = std::this_thread::get_id();
while (!m_bExit || m_nManual)
{
//等待超时
std::unique_lock<std::mutex> lock(m_mtx);
if (nTimeout)
{
m_Condition.wait_for(lock, std::chrono::milliseconds(nTimeout), [this](){return (m_nManual != 0); });
//调用回调函数
m_funCallback();
}
else
m_Condition.wait(lock, [this](){return (m_nManual != 0); });
if (m_bExit && m_nManual == 0)
return 0;
if (m_nManual)
m_nManual--;
}
//线程退出
return 0;
});
}
void CBT_Timer::StopTimer()
{
if (!m_bExit)
//停止计时器
//修改停止标识
m_bExit = true;
//通知一下阻塞事件
if (std::this_thread::get_id() != m_loopThreadID)
{
m_Condition.notify_one();
//等待线程退出
try
{
m_loopTask.get();
}
catch (...){}
}
}
void CBT_Timer::SetTimerEvent()
{
m_nManual++;
m_Condition.notify_one();
}