cpp
#pragma once
#include <boost/asio.hpp>
#include <functional>
#include <iostream>
#include <mutex>
class Throttler
{
public:
typedef std::chrono::steady_clock Clock;
typedef std::chrono::milliseconds Duration;
typedef Clock::time_point TimePoint;
Throttler(boost::asio::io_context& io, int intervalMs)
: _timer(io), _interval(std::chrono::milliseconds(intervalMs)), _ready(true)
{
}
~Throttler() { _timer.cancel(); }
template <typename F, typename... Args>
void exectue(F&& f, Args&&... args)
{
// 获取当前时间
auto now = Clock::now();
// 计算剩余等待时间
auto remaining = _interval - (now - _previous);
// 取消之前的定时器(如果有)
boost::system::error_code ec;
_timer.cancel(ec);
std::function<decltype(f(args...))()> func =
std::bind(std::forward<F>(f), std::forward<Args>(args)...);
// 如果不需要等待,立即执行函数
if (remaining <= Duration::zero())
{
func();
// 更新最后执行时间
_previous = now;
} else
{
// 需要等待,设置定时器延迟执行
_timer.expires_after(remaining);
// 异步等待定时器触发
_timer.async_wait([this, func](const boost::system::error_code& ec) {
// 定时器回调函数(在IO线程执行)
if (!ec)
{ // 只有定时器正常触发才执行 callback
func();
// 更新最后执行时间
_previous = Clock::now();
}
});
}
}
private:
boost::asio::steady_timer _timer;
Duration _interval; // 节流时间间隔
TimePoint _previous; // 上次执行的时间点
bool _ready;
};