日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++定时器的实现之格式修订版

發(fā)布時(shí)間:2023/12/2 c/c++ 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++定时器的实现之格式修订版 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

個(gè)人認(rèn)為一個(gè)完備的定時(shí)器需要有如下功能:

  • 在某一時(shí)間點(diǎn)執(zhí)行某一任務(wù)

  • 在某段時(shí)間后執(zhí)行某一任務(wù)

  • 重復(fù)執(zhí)行某一任務(wù)N次,任務(wù)間隔時(shí)間T

那么如何實(shí)現(xiàn)定時(shí)器呢?下面是我自己實(shí)現(xiàn)的定時(shí)器邏輯,源碼鏈接最后會附上。

定時(shí)器中主要的數(shù)據(jù)結(jié)構(gòu)

  • 優(yōu)先級任務(wù)隊(duì)列:隊(duì)列中存儲任務(wù),每個(gè)任務(wù)會添加時(shí)間戳,最近的時(shí)間戳的任務(wù)會先出隊(duì)。

  • 鎖和條件變量:當(dāng)有任務(wù)需要執(zhí)行時(shí),用于通知正在等待的線程從任務(wù)隊(duì)列中取出任務(wù)執(zhí)行。

  • 線程池:各個(gè)任務(wù)會放在線程池中執(zhí)行。

下面是相關(guān)代碼:

class TimerQueue {public: ?struct InternalS { ? ? ?std::chrono::time_point<std::chrono::high_resolution_clock> time_point_; ? ? ?std::function<void()> func_; ? ? ?bool operator<(const InternalS& b) const { return time_point_ > b.time_point_; } ?}; ?enum class RepeatedIdState { kInit = 0, kRunning = 1, kStop = 2 }; private: ?std::priority_queuequeue_; ?bool running_ = false; ?std::mutex mutex_; ?std::condition_variable cond_;wzq::ThreadPool thread_pool_;std::atomic<int> repeated_func_id_; ?wzq::ThreadSafeMap<int, RepeatedIdState> repeated_id_state_map_;};

如何開啟定時(shí)器功能

打開內(nèi)部的線程池功能,用于執(zhí)行放入定時(shí)器中的任務(wù),同時(shí)新開一個(gè)線程,循環(huán)等待任務(wù)到來后送入線程池中執(zhí)行。

bool Run() { ? ?bool ret = thread_pool_.Start(); ? ?if (!ret) { ? ? ? ?return false; ? ?} ? ?std::thread([this]() { RunLocal(); }).detach(); ? ?return true;} void RunLocal() { ? ?while (running_) { ? ? ? ?std::unique_lock<std::mutex> lock(mutex_); ? ? ? ?if (queue_.empty()) { ? ? ? ? ? ?cond_.wait(lock); ? ? ? ? ? ?continue; ? ? ? ?} ? ? ? ?auto s = queue_.top(); ? ? ? ?auto diff = s.time_point_ - std::chrono::high_resolution_clock::now(); ? ? ? ?if (std::chrono::duration_cast<std::chrono::milliseconds>(diff).count() > 0) { ? ? ? ? ? ?cond_.wait_for(lock, diff); ? ? ? ? ? ?continue; ? ? ? ?} else { ? ? ? ? ? ?queue_.pop(); ? ? ? ? ? ?lock.unlock(); ? ? ? ? ? ?thread_pool_.Run(std::move(s.func_)); ? ? ? ?} ? ?}}

如何在某一時(shí)間點(diǎn)執(zhí)行任務(wù)

根據(jù)時(shí)間戳構(gòu)造InternalS,放入隊(duì)列中:

template <typename F, typename... Args> void AddFuncAtTimePoint(const std::chrono::time_point<std::chrono::high_resolution_clock>& time_point, F&& f, ? ? ? ? ? ? ? ? ? ? ? ?Args&&... args) { ? ?InternalS s; ? ?s.time_point_ = time_point; ? ?s.func_ = std::bind(std::forward(f), std::forward(args)...); ? ?std::unique_lock<std::mutex> lock(mutex_); ? ?queue_.push(s); ? ?cond_.notify_all();}

如何循環(huán)執(zhí)行任務(wù)

首先為這個(gè)循環(huán)任務(wù)生成標(biāo)識ID,外部可以通過ID來取消此任務(wù)繼續(xù)執(zhí)行,代碼如下,內(nèi)部以類似遞歸的方式循環(huán)執(zhí)行任務(wù)。

template <typename R, typename P, typename F, typename... Args>int AddRepeatedFunc(int repeat_num, const std::chrono::duration& time, F&& f, Args&&... args) { ? ?int id = GetNextRepeatedFuncId(); ? ?repeated_id_state_map_.Emplace(id, RepeatedIdState::kRunning); ? ?auto tem_func = std::bind(std::forward(f), std::forward(args)...); ? ?AddRepeatedFuncLocal(repeat_num - 1, time, id, std::move(tem_func)); ? ?return id;} int GetNextRepeatedFuncId() { return repeated_func_id_++; } template <typename R, typename P, typename F>void AddRepeatedFuncLocal(int repeat_num, const std::chrono::duration& time, int id, F&& f) { ? ?if (!this->repeated_id_state_map_.IsKeyExist(id)) { ? ? ? ?return; ? ?} ? ?InternalS s; ? ?s.time_point_ = std::chrono::high_resolution_clock::now() + time; ? ?auto tem_func = std::move(f); ? ?s.repeated_id = id; ? ?s.func_ = [this, &tem_func, repeat_num, time, id]() { ? ? ? ?tem_func(); ? ? ? ?if (!this->repeated_id_state_map_.IsKeyExist(id) || repeat_num == 0) { ? ? ? ? ? ?return; ? ? ? ?} ? ? ? ?AddRepeatedFuncLocal(repeat_num - 1, time, id, std::move(tem_func)); ? ?}; ? ?std::unique_lock<std::mutex> lock(mutex_); ? ?queue_.push(s); ? ?lock.unlock(); ? ?cond_.notify_all();}

聲明:

本文于網(wǎng)絡(luò)整理,版權(quán)歸原作者所有,如來源信息有誤或侵犯權(quán)益,請聯(lián)系我們刪除或授權(quán)事宜。

總結(jié)

以上是生活随笔為你收集整理的C++定时器的实现之格式修订版的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。