当前位置: 首页 > news >正文

宁波网站建设公司地址联系方式 响应式网站

宁波网站建设公司地址,联系方式 响应式网站,莱芜app下载,做黑彩票的网站赚钱1#xff1a;简单基础 定时器的核心知识点#xff0c;对我来说就是获取当前时间和设置回调函数。 简单练习#xff1a; ​ c语言通过gettimeofday 获取当前时间并进行处理 ​ 回调函数的定义#xff08;函数参数有必要适当存储#xff09; typedef void(Timerfunc)(vo…1简单基础 定时器的核心知识点对我来说就是获取当前时间和设置回调函数。 简单练习 ​ c语言通过gettimeofday 获取当前时间并进行处理 ​ 回调函数的定义函数参数有必要适当存储 typedef void(Timerfunc)(void p); 1.1 简单源码演示 #include stdio.h #include sys/time.h #include unistd.h //sleep typedef unsigned long int uint64_t; static uint64_t GetCurrentTime() {struct timeval tv;gettimeofday(tv, NULL);return tv.tv_sec * 1000 tv.tv_usec / 1000; }void callback(void * p) {int * i (int *)p;printf(callback %d\n, *i); }int main() {uint64_t mytest 1;printf(%lu \n, GetCurrentTime());sleep(2);struct timeval tv;gettimeofday(tv, NULL);printf(second: %ld\n, tv.tv_sec); // 秒printf(millisecond: %ld\n, tv.tv_sec * 1000 tv.tv_usec / 1000); // 毫秒printf(microsecond: %ld\n, tv.tv_sec * 1000000 tv.tv_usec); // 徽秒sleep(3); // 让程序休眠3秒printf(---------------------sleep 3 second-------------------\n);gettimeofday(tv, NULL);printf(second: %ld\n, tv.tv_sec); // 秒printf(millisecond: %ld\n, tv.tv_sec * 1000 tv.tv_usec / 1000); // 毫秒printf(microsecond: %ld\n, tv.tv_sec * 1000000 tv.tv_usec); // 徽秒 //回调函数的简单定义和使用typedef void(*Timerfunc)(void* p);int func_para 3;Timerfunc m_func callback;void * para (void*)func_para;(*m_func)(para);return 0; } 1.2 运行结果 rootaliy:/home/leetcode# ./get_time1 1739506868441 second: 1739506870 millisecond: 1739506870441 microsecond: 1739506870441927 ---------------------sleep 3 second------------------- second: 1739506873 millisecond: 1739506873442 microsecond: 1739506873442060 callback 32借助已有的stl容器实现是最方便的 不知道哪里参考的一个代码借助了stl中的一个优先级队列就简单整理一下吧。 回顾好久没写的细节 0优先级队列 priority_queue 支持大堆小堆 自己定义比较函数 1锁和条件变量 条件变量的几种信号等待方式。 2chrono下的相关获取时间的接口需要梳理一下。 3std::function 和lamba需要回顾练习一下 4stl的push时可以直接构造结构体对象task_queue.push(Task{func, exec_time}); 5条件变量中的wait 以及wait_until ​ 》 已经有唤醒 wait用条件等待 防止虚假唤醒 ​ 》wait_until 接口可以实现等待到特定时间后进行执行系统调用内部定时器实现 会虚假唤醒吗。 和自己代码实现时间差同功能 2.1练习源码 都是C11的东东 需要回顾。 //定时器的简单实现 借助stl容器使用线程进行专门的定时器处理。//容器中保存了定时器的超时时间以及对应的回调函数 #include stdio.h #include iostream #include functional #include mutex #include thread #include chrono #include vector #include condition_variable #include atomic #include queueclass Timer{ private:std::thread worker;std::atomicbool stop;//锁和条件变量std::mutex queue_mutex;std::condition_variable condition;struct Task{std::functionvoid(void) func;//std::chrono::steady_clock 只能增加的单调时钟 std::chrono::time_point表示某一刻的对象//这里时间的相关接口需要参考chronostd::chrono::time_pointstd::chrono::steady_clock exec_time; //为了给wait_until做参数 直接指定bool operator (const Task other) const{return exec_time other.exec_time;}};//优先队列 用task为元素类型 以std::vectorTask 进行存储 按照默认的比较函数进行比较 实现最小堆std::priority_queueTask, std::vectorTask, std::greaterTask task_queue; //底层是堆的结构private:void run(){while(!stop){//这里进行死循环 或者加锁条件变量实现队列中任务的提取if(task_queue.empty()){std::unique_lockstd::mutex lock(queue_mutex);//防止虚假唤醒condition.wait(lock, [this] {return !this-task_queue.empty() || this-stop;});//这里无法访问类的成员变量 如何函数内部或者全局变量 即可以// condition.wait(lock, [] {// return !task_queue.empty() || stop;// });} if(task_queue.empty() || stop){return;}{// auto now std::chrono::steady_clock::now();auto exec_task_time task_queue.top().exec_time; //目标执行的时间std::unique_lockstd::mutex lock(queue_mutex);//注意第二个参数 是当前时间加上最大等待时间 if(condition.wait_until(lock, exec_task_time) std::cv_status::timeout){auto task task_queue.top();task_queue.pop();lock.unlock();task.func(); //这里没有定义参数 可以定义参数为自己}}}}public:Timer():stop(false), worker(Timer::run, this){}~Timer(){ //单例时才把构造函数析构函数设置为私有stop true;condition.notify_all();worker.join();}static inline time_t get_Clock(){// 获取当前时间点auto now std::chrono::steady_clock::now();// 获取从纪元到现在所经过的持续时间auto duration now.time_since_epoch();//转换为毫秒并返回return std::chrono::duration_caststd::chrono::milliseconds(duration).count();}void schedule(const std::functionvoid() func, int delay_ms){auto exec_time std::chrono::steady_clock::now() std::chrono::milliseconds(delay_ms);{std::unique_lockstd::mutex lock(queue_mutex);task_queue.push(Task{func, exec_time}); //注意这里的细节}condition.notify_all();} };int main() {Timer timer;printf(now %lu \n, Timer::get_Clock());timer.schedule([](){printf(exec 1000 %lu \n, Timer::get_Clock());}, 1000);timer.schedule([](){printf(exec 3000 %lu \n, Timer::get_Clock());}, 3000);std::this_thread::sleep_for(std::chrono::seconds(5));return 0; }2.2 运行结果 ootaliy:/home/leetcode# g my_timer1.c -o my_timer -stdc11 rootaliy:/home/leetcode# ./my_timer now 16306525752 exec 1000 16306526753 exec 3000 16306528753 3总结一些其他遗留 定时器的实现中往往需要数据结构配合。时间戳和回调 需要支持排序 需要方便插入 1红黑树存储数据结构 比如set map mutilset mutilmap 以及nginx下封装的红黑树。 2使用最小堆进行存储。 3跳表有序可以快速插入 参考redis中的跳表源码/时间轮定时器。 3.1时间轮定时器 3.2一个来自别人的demo代码练习 std::vector 模拟数据结构 这样设计有最大超时时间限制吧然后轮询也有精度。 存储的是节点指针增加引用计数实现多次执行类型心跳 //时间轮定时器 采用数组链表链表结合vector的方式存储数据结构 采用轮询的方式处理事件#include unistd.h #include iostream #include vector #include list using namespace std;#include sys/time.h//同一个指针对象 多次加入只是引用计数增加 执行次数增加。 class CTimerNode { public:CTimerNode(int fd) : id(fd), ref(0) {}void Offline() {this-ref 0;}//通过引用计数的方式 确定是否销毁该对象 加入时 消费时-- //可能多次加入定时器 bool TryKill() {if (this-ref 0) return true;DecrRef();if (this-ref 0) {cout id is killed down endl;return true;}cout id ref is ref endl;return false;}void IncrRef() {this-ref;}protected:void DecrRef() {this-ref--;}private:int ref;int id; };const int TW_SIZE 16; const int EXPIRE 10; const int TW_MASK TW_SIZE - 1; static size_t iRealTick 0; //链表的节点 typedef listCTimerNode* TimeList; typedef TimeList::iterator TimeListIter; //用vectorlist 构造时间轮数据结构 typedef vectorTimeList TimeWheel;void AddTimeout(TimeWheel tw, CTimerNode *p) {if (p) {p-IncrRef();TimeList le tw[(iRealTickEXPIRE) TW_MASK]; //基于当前的时间 放入对应的list中 le.push_back(p);} }// 用来表示delay时间后调用 void AddTimeoutDelay(TimeWheel tw, CTimerNode *p, size_t delay) {if (p) {p-IncrRef();TimeList le tw[(iRealTickEXPIREdelay) TW_MASK];le.push_back(p);} }//命中 void TimerShift(TimeWheel tw) {size_t tick iRealTick;iRealTick;TimeList le tw[tick TW_MASK]; //每次向前走一个//循环遍历轮子 消费轮子中的第一个节点对应的list中的所有事件TimeListIter iter le.begin();for (; iter ! le.end();iter) {CTimerNode *p *iter;if (p p-TryKill()) {delete p;}}le.clear(); }static time_t current_time() {time_t t;struct timeval tv;gettimeofday(tv, NULL);t (time_t)tv.tv_sec;return t; //这里返回的是秒 }int main () {TimeWheel tw(TW_SIZE);CTimerNode *p new CTimerNode(10001);AddTimeout(tw, p); //加入时间轮定时器中AddTimeoutDelay(tw, p, 5); //对象已经存在 5s后执行对应的回调time_t start current_time();for (;;) {time_t now current_time();//这里以秒为单位 进行依次命中轮询if (now - start 0) {for (int i0; inow-start; i)TimerShift(tw);start now;cout check timer shift iRealTick endl;}usleep(2500); //2500 微妙 2.5ms}return 0; } 3.3 :demo运行 同一个TimerNode节点只是把指针加入了时间轮中。 每次处理节点时根据引用计数进行判断了。 rootaliy:/home/leetcode# ./wheel_timer check timer shift 1 check timer shift 2 check timer shift 3 check timer shift 4 check timer shift 5 check timer shift 6 check timer shift 7 check timer shift 8 check timer shift 9 check timer shift 10 10001 ref is 1 check timer shift 11 check timer shift 12 check timer shift 13 check timer shift 14 check timer shift 15 10001 is killed down3.4更复杂的时间轮 linux内核中使用比较复杂的时间轮来进行定时器的处理 参考时钟的时针 分针 秒针多个类似上面的时间轮进行配合采用不同的精度配合实现更复杂的功能只有第一层消费后面的基层都是按层移动到上一层。
http://www.pierceye.com/news/611169/

相关文章:

  • 网站开发类型什么意思网页制作与设计千年之恋代码
  • 怎么做公司的网站免费网站建设专业的公司
  • 适合这手机浏览器主页的网站wordpress本地上传服务器
  • 济南百度网站开发寮步镇做网站
  • 营销类型的公司网站专注高密做网站哪家好
  • 公司网站建设找谁做网络渠道
  • 网站建设公司 校园网站html5商城网站
  • 自学it做网站厦门网站推广¥做下拉去118cr
  • 汕头市做网站优化国内时事新闻
  • 网站文章来源seowordpress 搜索 分词
  • 网站建设和网络推广微信开发品牌
  • 湛江网站关键词优化百度推广优化技巧
  • 做盗版网站会怎样网页设计规范2018
  • 做个中英文网站多少钱网页设计图片作品
  • iis7 添加php网站网站为什么需要空间
  • 网站到首页排名h5怎么制作的
  • 网站制作教程 pdf下载培训网站制作网站
  • 网站开发文档范例国外服务器租用价格表
  • 六安网站制作费用怎么做百度提交入口网站
  • centos7做网站做pc端网站讯息
  • 驻马店建设网站安徽全过程网站搭建案例
  • 企业网站推广费用wordpress相册汉化版
  • 怎么做正规网站广告网站设计怎么样
  • 深圳营销型网站公司电话云渲染网站开发
  • 生成网站有吗免费的网站建设服务有哪些内容
  • 网站建设制作公司思企互联超级采购小程序怎么注册
  • 燕郊做网站找谁wordpress登录修改
  • 大概开发一个网站多少钱php做网站商城系统怎么样
  • wordpress网站程序员登录百度账号
  • wordpress trac网站优化公司哪家好