前言:
现时朋友们对“c语言定时调用函数”大约比较注重,姐妹们都需要分析一些“c语言定时调用函数”的相关资讯。那么小编同时在网络上汇集了一些对于“c语言定时调用函数””的相关内容,希望姐妹们能喜欢,姐妹们快快来学习一下吧!定时管理器
定时器是一种常用的组件, 一般的框架都提供,可惜c++标准库没有提供。
下面实现一个简单通用的定时管理器
#include <map>#include <mutex>#include <chrono>#include <memory>#include <thread>#include <functional>class TimerMgr { struct TimerMgr::Timer;public: TimerMgr(int maxThreads = 3, int intervalMilliseconds = 100) : m_maxThreads(maxThreads), m_interval(intervalMilliseconds){} ~TimerMgr() { Stop(); } void Stop() { m_exit = true; while (!m_threads.empty()) { if (m_threads.begin()->second.joinable()) { m_threads.begin()->second.join(); } m_threads.erase(m_threads.begin()); } } //添加定时器, 返回定时器ID int AddTimer(int milliseconds, std::weak_ptr<std::function<void()>> func, bool exclusive = false) { std::shared_ptr<std::function<int(int)>> backFunc = std::make_shared<std::function<int(int)>>([func](int id)->int { std::shared_ptr<std::function<void()>> upFunc(func.lock()); if (upFunc == nullptr) { return -1; } upFunc->operator()(); return 0; }); return AddTimer(milliseconds, exclusive, backFunc, backFunc); } //添加定时器, 返回定时器ID int AddTimer(int milliseconds, std::weak_ptr<std::function<void(int)>> func, bool exclusive = false) { std::shared_ptr<std::function<int(int)>> backFunc = std::make_shared<std::function<int(int)>>([func](int id)->int { std::shared_ptr<std::function<void(int)>> upFunc(func.lock()); if (upFunc == nullptr) { return -1; } upFunc->operator()(id); return 0; }); return AddTimer(milliseconds, exclusive, backFunc, backFunc); } //添加定时器, 返回定时器ID int AddTimer(int milliseconds, std::weak_ptr<std::function<int(int)>> func, bool exclusive = false) { return AddTimer(milliseconds, exclusive, func, nullptr); } //删除定时器, 输入参数为定时器ID void RemoveTimer(int timerId) { std::lock_guard<std::mutex> lock(m_mutex); auto iter = m_timers.find(timerId); if (iter != m_timers.end()) { iter->second.remove = true; } }private: bool GetActive(struct TimerMgr::Timer*& timer) { using namespace std::chrono; std::lock_guard<std::mutex> lock(m_mutex); int64_t now = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count(); for (auto iter = m_timers.begin(); iter != m_timers.end(); ) { if (iter->second.remove && !iter->second.active) { //清理已经失效的定时器 if (iter->second.exclusive && m_threads[iter->first].joinable()) { m_threads[iter->first].join(); m_threads.erase(iter->first); } m_timers.erase(iter++); continue; } if (iter->second.active || iter->second.exclusive || now < iter->second.activeTime) { ++iter; continue; } iter->second.active = true; timer = &iter->second; return true; } return false; } int AddTimer(int millisec, bool exclusive, std::weak_ptr<std::function<int(int)>> cbFunc, std::shared_ptr<std::function<int(int)>> backFunc = nullptr) { using namespace std::chrono; std::lock_guard<std::mutex> lock(m_mutex); if (m_exit) { return -1; } //寻找新的定时器ID while (m_timers.end() != m_timers.find(m_maxTimerId)) { m_maxTimerId = (m_maxTimerId > 0x3FFFFFFE) ? 1 : m_maxTimerId + 1; } //定时器间隔时间不能小于100毫秒 millisec = (millisec < 100) ? 100 : millisec; struct Timer timer; timer.id = m_maxTimerId++; timer.exclusive = exclusive; timer.millisec = millisec; timer.activeTime = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count() + millisec; timer.cbFunc = cbFunc; timer.backFunc = backFunc; m_timers[timer.id] = timer; if (!m_init) { //没有初始化,则在这里初始化定时器线程 m_init = true; for (int i = 1; i <= m_maxThreads; i++) { m_threads[0 - i] = std::thread([this]() { struct Timer* timer = nullptr; do { if (!GetActive(timer)) { std::this_thread::sleep_for(milliseconds(m_interval)); continue; } std::shared_ptr<std::function<int(int)>> func(timer->cbFunc.lock()); timer->remove = (func == nullptr || 0 != func->operator()(timer->id)); timer->activeTime = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count() + timer->millisec; timer->active = false; } while (!m_exit); }); } } if (exclusive) { //排它性的定时器,单独创建一个线程处理 struct Timer& _timer = m_timers[timer.id]; m_threads[timer.id] = std::thread([this, &_timer]() { _timer.active = true; bool over(false); do { int64_t now = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count(); if (now < _timer.activeTime) { std::this_thread::sleep_for(milliseconds((_timer.activeTime - now > 1000) ? 1000 : _timer.activeTime - now)); continue; } std::shared_ptr<std::function<int(int)>> func(_timer.cbFunc.lock()); over = (func == nullptr || 0 != func->operator()(_timer.id)); _timer.activeTime = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count() + _timer.millisec; } while (!m_exit && !over); _timer.active = false; _timer.remove = true; }); } return timer.id; }private: int m_maxTimerId = 1; int m_interval = 100; int m_maxThreads = 3; bool m_init = false; bool m_exit = false; std::mutex m_mutex; std::map<int, struct TimerMgr::Timer> m_timers; std::map<int, std::thread> m_threads;private: struct Timer { int id = 0; int millisec = 0; bool exclusive = false; bool active = false; bool remove = false; int64_t activeTime = 0; std::weak_ptr<std::function<int(int)>> cbFunc = std::weak_ptr<std::function<int(int)>>(); std::shared_ptr<std::function<int(int)>> backFunc = nullptr; };};
文心一言的解析如下:
这段代码是一个C++类的部分实现,这个类似乎被命名为TimerMgr。以下是对这段代码的详细解释:
私有成员变量:
* `m_maxTimerId`: 这是当前使用的最大定时器ID,初始化为1。* `m_interval`: 定时器的间隔时间,单位为毫秒,初始化为100毫秒。* `m_maxThreads`: 最大线程数,初始化为3。* `m_init`: 一个布尔值,表示是否已经初始化。初始化为false。* `m_exit`: 一个布尔值,表示是否应该退出。初始化为false。* `m_mutex`: 一个互斥锁,用于保护类的成员变量,防止多个线程同时访问它们。* `m_timers`: 一个映射,将定时器ID映射到`Timer`结构体实例。* `m_threads`: 一个映射,将线程ID映射到线程对象。私有结构体 Timer:
* `id`: 定时器的唯一标识符。* `millisec`: 定时器的时间间隔,单位为毫秒。* `exclusive`: 一个布尔值,表示这个定时器是否是独占的。* `active`: 一个布尔值,表示定时器是否处于活动状态。* `remove`: 一个布尔值,表示是否应该移除这个定时器。* `activeTime`: 定时器的下次活动时间。* `cbFunc`: 一个弱引用到`std::function<int(int)>`,它是一个回调函数,当定时器激活时会被调用。* `backFunc`: 一个共享引用到`std::function<int(int)>`,它也是一个回调函数,但它的用途在这段代码中没有明确说明。
这段代码定义了三个重载的 AddTimer 函数,它们都是用来添加计时器的。每个函数都接受不同的参数,并返回一个整数(定时器ID)。
第一个 AddTimer 函数接受一个整数 milliseconds 和一个 std::weak_ptr<std::function<void()>> func,其中 func 是一个可以被调用的对象(例如函数指针、Lambda 表达式等)。该函数创建一个新的 std::shared_ptr<std::function<int(int)>> backFunc,这个新的函数在被调用时会尝试对 func 进行加锁,如果成功则调用 func,否则返回 -1。然后它调用另一个 AddTimer 函数,将 backFunc 作为回调函数和之前的参数一起传入。第二个 AddTimer 函数与第一个类似,但是它接受一个额外的参数 std::weak_ptr<std::function<void(int)>> func,这个函数接受一个整数参数。其他部分与第一个函数相同。第三个 AddTimer 函数也是创建一个新的回调函数 backFunc,但是它不接受任何参数。然后它调用另一个 AddTimer 函数,将 backFunc 作为回调函数和之前的参数一起传入。
最后,这三个函数都返回一个整数(定时器ID),可能是添加计时器的结果(例如成功或失败)。
示例:
int main() { std::shared_ptr<std::function<void()>> cbFunc1 = std::make_shared<std::function<void()>>([]() { std::cout << "timer_id : no case timer_id" << std::endl; }); std::shared_ptr<std::function<void(int)>> cbFunc2 = std::make_shared<std::function<void(int)>>([](int id) { std::cout << "timer_id : "<< id << std::endl; }); std::shared_ptr<std::function<int(int)>> cbFunc3 = std::make_shared<std::function<int(int)>>([](int id) { std::cout << "timer_id : " << id << std::endl; return 0; }); TimerMgr timerMgr; int tId1 = timerMgr.AddTimer(500, cbFunc1); int tId2 = timerMgr.AddTimer(500, cbFunc2); int tId3 = timerMgr.AddTimer(500, cbFunc3, true); std::this_thread::sleep_for(std::chrono::seconds(5)); return 0;}
标签: #c语言定时调用函数