网站开发毕业设计评审表wordpress 优秀作者
web/
2025/9/30 20:00:11/
文章来源:
网站开发毕业设计评审表,wordpress 优秀作者,wordpress自媒体插件,许昌做网站联系电话一.定时器#xff08;timer#xff09;的需求
1.执行定时任务的时#xff0c;主线程不阻塞#xff0c;所以timer必须至少持有一个线程用于执行定时任务 2.考虑到timer线程资源的合理利用#xff0c;一个timer需要能够管理多个定时任务#xff0c;所以timer要支持增删任务…一.定时器timer的需求
1.执行定时任务的时主线程不阻塞所以timer必须至少持有一个线程用于执行定时任务 2.考虑到timer线程资源的合理利用一个timer需要能够管理多个定时任务所以timer要支持增删任务通过容器储存任务 3.当timer空闲时即没有任务或执行任务的时刻未到timer中的线程不应该空转来占用资源可通过条件变量实现 4.支持重复任务和非重复任务
二.定时器timer的实现
#include algorithm
#include atomic
#include chrono
#include condition_variable
#include functional
#include map
#include mutex
#include thread
#include iostream
#include iomanip
#include sstreamnamespace CC
{
using TaskFunc std::functionvoid();struct Task
{uint64_t id;uint64_t period;bool repeated;TaskFunc func;bool removed;Task(uint64_t id, uint64_t period, bool repeated, TaskFunc func): id(id), period(period), repeated(repeated), func(func), removed(false){}
};class Timer
{
public:Timer() : m_stop(false){m_worker std::thread(Timer::run, this);}~Timer(){m_stop.store(true);m_condition.notify_all();m_worker.join();}uint64_t add(uint64_t period_ms, bool repeated, TaskFunc func){uint64_t when now() period_ms;Task task(m_cur_id, period_ms, repeated, func);{std::lock_guardstd::mutex lock(m_tasks_mutex);m_tasks.insert({when, task});}m_condition.notify_all();return m_cur_id;}// Timer::remove并没有真正的将定时任务删除仅仅是将removed标志位设置为true删除操作实际是在Timer::run中进行的。// 为什么要这么做如果在这里如果由Timer::remove来执行m_tasks.erase(it)那么有可能删除的是Timer::run里正在执行的那个任务这是明显不对的。// 所以才采用将removed标志位设置为true的这种做法。bool remove(uint64_t id){bool flag false;std::lock_guardstd::mutex lock(m_tasks_mutex);std::multimapuint64_t, Task::iterator it std::find_if(m_tasks.begin(), m_tasks.end(),[id](const std::pairuint64_t, Task item) - bool { return item.second.id id; });if (it ! m_tasks.end()){it-second.removed true;flag true;}return flag;}private:std::thread m_worker;std::atomicbool m_stop;std::multimapuint64_t, Task m_tasks;std::mutex m_tasks_mutex;std::condition_variable m_condition;uint64_t m_cur_id;// m_condition.wait之后继续向下执行此时如果m_stop是true那么表明timer要被停止了那线程也要结束所以一个break跳出最开始的while (true)循环让线程执行结束。// 如果m_stop是false那表明现有可能有定时任务需要执行了。取出第一个任务m_tasks.begin()也是按时间排序最靠前的任务。用任务的时刻和当前时刻对比// 如果“时辰已到”那就执行。执行的之后需要注意的是要将锁释放lock.unlock()因为继续持有没有任何意义反而会阻塞住对m_tasks的一些操作。// 如果“时辰未到”那就执行m_condition.wait_for让当前线程休眠直到std::chrono::milliseconds(task_time - cur_time)这段时间过去或者被唤醒。void run(){while (true){std::unique_lockstd::mutex lock(m_tasks_mutex);m_condition.wait(lock, [this]() - bool { return !m_tasks.empty() || m_stop; });if (m_stop){break;}uint64_t cur_time now();std::multimapuint64_t, Task::iterator it m_tasks.begin();uint64_t task_time it-first;if (cur_time task_time){Task cur_task it-second;if (!cur_task.removed){lock.unlock();cur_task.func();lock.lock();if (cur_task.repeated !cur_task.removed){uint64_t when cur_time cur_task.period;Task new_task(cur_task.id, cur_task.period, cur_task.repeated, cur_task.func);m_tasks.insert({when, new_task});}}m_tasks.erase(it);}else{m_condition.wait_for(lock, std::chrono::milliseconds(task_time - cur_time));}}}uint64_t now() //ms{auto now std::chrono::system_clock::now();auto duration now.time_since_epoch();return std::chrono::duration_caststd::chrono::milliseconds(duration).count();}
};} // namespace CC// 格式化时间精确到毫秒.
std::string getTimeString()
{auto now std::chrono::system_clock::now();auto duration now.time_since_epoch();auto millis std::chrono::duration_caststd::chrono::milliseconds(duration).count();std::time_t time std::chrono::system_clock::to_time_t(now);std::tm *tm std::localtime(time);std::stringstream ss;ss std::put_time(tm, %Y-%m-%d %H:%M:%S) . std::setw(3) std::setfill(0) millis % 1000;return ss.str();
}// 待执行的任务
void theTask(int id)
{std::cout getTimeString() id id std::endl;
}int main()
{CC::Timer *timer new CC::Timer();timer-add(3000, false, std::bind(theTask, 1));uint64_t id timer-add(2000, true, std::bind(theTask, 2));timer-add(1000, true, std::bind(theTask, 3));std::this_thread::sleep_for(std::chrono::seconds(3));timer-remove(id);std::this_thread::sleep_for(std::chrono::seconds(1));delete timer;std::this_thread::sleep_for(std::chrono::seconds(1));return 0;
} 参考链接https://zhuanlan.zhihu.com/p/668916073
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/84629.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!