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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

优先队列实现定时器

發布時間:2023/12/20 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 优先队列实现定时器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

http://www.cnblogs.com/lewiskyo/p/6359789.html?上文介紹了使用數組實現定時器,但因為插入和刪除定時器的效率太低,所以這里改用優先隊列實現一次。

?

實現代碼如下:

1 #include <iostream> 2 #include <sys/time.h> 3 #include <unistd.h> 4 #include <thread> 5 #include <vector> 6 #include <map> 7 #include <memory> 8 #include <mutex> 9 #include <stdlib.h> 10 #include <algorithm> 11 #include <queue> 12 13 using namespace std; 14 15 #define THREAD_COUNT 4 16 17 typedef struct TimerInfo 18 { 19 int id; 20 long expired; //超時時間戳(ms) 21 bool is_working; //用于判斷該定時器是否有效 22 bool is_repeat; // 是否為循環定時器標識 23 long interval; //循環定時器循環間隔 24 25 } TimerInfo; 26 27 // 排序函數 28 class comp 29 { 30 public: 31 bool operator()(const shared_ptr<TimerInfo> &t1, const shared_ptr<TimerInfo> &t2) 32 { 33 if(t1.get()->expired > t2.get()->expired) 34 return true; 35 else 36 return false; 37 } 38 }; 39 40 41 typedef struct TimerMng 42 { 43 int id; 44 45 priority_queue<shared_ptr<TimerInfo>, vector<shared_ptr<TimerInfo> >, comp> timer_queue; // 優先隊列 46 map<int, shared_ptr<TimerInfo> > timer_map; //id到定時器的映射 用于根據id取消定時器 47 48 mutex mtx; 49 50 struct timeval now; 51 52 TimerMng() 53 { 54 id = 0; 55 } 56 57 } TimerMng; 58 59 TimerMng t_mng; 60 61 void add_timer(bool is_repeat, long expired, long interval) 62 { 63 TimerInfo *t_info = new TimerInfo(); 64 t_info->is_repeat = is_repeat; 65 t_info->expired = expired; 66 t_info->interval = interval; 67 t_info->is_working = true; 68 69 shared_ptr<TimerInfo> timer_info(t_info); 70 71 lock_guard<mutex> guard(t_mng.mtx); 72 int now_id = t_mng.id++; 73 t_info->id = now_id; 74 75 t_mng.timer_queue.push(timer_info); 76 77 t_mng.timer_map.insert(pair<int, shared_ptr<TimerInfo> >(now_id, timer_info) ); 78 79 } 80 81 void update_time() 82 { 83 gettimeofday(&t_mng.now, NULL); 84 } 85 86 void execute_timer() 87 { 88 long now_usec = t_mng.now.tv_sec * 1000 + t_mng.now.tv_usec / 1000; 89 90 while(true) 91 { 92 lock_guard<mutex> guard(t_mng.mtx); 93 94 if (t_mng.timer_queue.empty()) 95 break; 96 97 shared_ptr<TimerInfo> first = t_mng.timer_queue.top(); 98 99 if (first.get()->expired > now_usec ) 100 break; 101 102 if (first.get()->is_working) 103 { 104 // do something here 105 cout << "timer execute succ, now: " << now_usec << " id: " << first.get()->id << " " << "expired: " << first.get()->expired << endl; 106 } 107 108 map<int, shared_ptr<TimerInfo> >::iterator map_iter = t_mng.timer_map.find( first.get()->id); 109 110 // 從map中移除 111 t_mng.timer_map.erase(map_iter); 112 113 // 從隊列中移除 114 t_mng.timer_queue.pop(); 115 116 } 117 } 118 119 120 void timer_thread() 121 { 122 while(1) 123 { 124 update_time(); 125 execute_timer(); 126 // 1ms 1次循環 127 usleep(1000); 128 } 129 } 130 131 void worker_thread() 132 { 133 srand((unsigned)time(0)); 134 while(1) 135 { 136 struct timeval now; 137 gettimeofday(&now, NULL); 138 139 int rand_sec = rand() % 5 + 1; 140 int rand_usec = rand() % 900000 + 1; 141 142 long expired = (now.tv_sec + rand_sec) * 1000 + ( rand_usec / 1000 ); 143 add_timer(false, expired, 0); 144 145 sleep(rand() % 2 + 1); 146 } 147 } 148 149 150 int main() 151 { 152 thread t1(timer_thread); 153 154 vector<thread> v_thread; 155 156 for (int i = 0; i < THREAD_COUNT; ++i) 157 { 158 v_thread.push_back(thread(worker_thread)); 159 } 160 161 t1.join(); 162 163 for (int i = 0; i < THREAD_COUNT; ++i) 164 { 165 v_thread[i].join(); 166 } 167 }

?

代碼與使用數組實現的大致相同,只是換了隊列實現,而且在add_timer時直接使用優先隊列的接口 push,

在移除定時器時使用接口 pop即可.

?

實現效率:

add_timer 已序堆中添加數據 O(log(N)).

execute_timer 最小已序堆中刪除根節點,選取新的根節點 O(log(N)).

可見比起數組實現的效率要高.

?

優先隊列(堆)的性質可以參考: http://blog.csdn.net/zhang20072844/article/details/10286997

轉載于:https://www.cnblogs.com/lewiskyo/p/6359858.html

總結

以上是生活随笔為你收集整理的优先队列实现定时器的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。