博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(P28)muduo_base库源码分析:定时器,lower_bound&upper_bound,RVO
阅读量:4299 次
发布时间:2019-05-27

本文共 2163 字,大约阅读时间需要 7 分钟。

文章目录

1.定时器

  • muduo的定时器由三个类实现,TimerId(外部类)、Timer、TimerQueue,用户只能看到第一个类,其它两个都是内部实现细节
  • TimerQueue的接口很简单,只有两个函数addTimer和cancel
  • EventLoop
runAt		在某个时刻运行定时器runAfter		过一段时间运行定时器runEvery		每隔一段时间运行定时器上面三个函数会调用到TimerQueue.addTimer()cancel		取消定时器会调用到TimerQueue.cancel()
  • TimerQueue数据结构的选择,能快速根据当前时间找到已到期的定时器(到期的定时器能够按照时间先后进行排序),也要高效的添加和删除Timer,因而可以用二叉搜索树,用map或者set
不使用map的原因是:map
,因为TimerQueue管理了很多定时器,有可能2个定时器的时间戳Timestamp是一样的,但是实际的定时器操作Timer*是不一样的。这是不可能的。map不支持key是一样的可以使用multimap,但是multimap不常用,还是算了。尽量回避不常用的容器!!使用set的原因是:typedef std::pair
Entry;typedef std::set
TimerList;//set只包含一个key,key的类型是pair对
是整个key,即使Timestamp相等,但是定时器的地址Timer*也是不等的,所以key也是不等的。
  • Channel的时序图
    在这里插入图片描述
  • EventLoop时序图
    (1)Poller返回了activeChannels,首先回调handleEvent(),handleEvent()会根据Channels是POLLIN可读还是可写事件?来调用TimerQueue.handleRead();
    (2)TimerQueue.handleRead()会getExpired()获取所有的超时的定时器,回调onTimer();
    在这里插入图片描述
  • eg:
    28\jmuduo\muduo\net\TimerId.h
    28\jmuduo\muduo\net\Timer.h
    28\jmuduo\muduo\net\Timer.cc
    28\jmuduo\muduo\base\Timestamp.h
    28\jmuduo\muduo\net\TimerQueue.h
    28\jmuduo\muduo\net\TimerQueue.cc
    28\jmuduo\muduo\net\CMakeLists.txt

2.lower_bound&upper_bound

  • eg1:
#include 
#include
using namespace std;int main(void){
int a[] = {
1, 2, 3, 4, 5 }; set
s(a, a+5);//key是int,set和map都会自动排序的 cout<<*s.lower_bound(2)<
=2的迭代器的位置,取*,//应该返回=2 cout<<*s.upper_bound(2)<
=2的迭代器的位置,取*,应该返回=3 return 0;}
  • 测试:
    在这里插入图片描述

3.RVO

  • 返回值优化(Return Value Optimization,简称RVO)是一种编译器优化机制

  • eg:

struct Foo   {
Foo() {
cout << "Foo ctor" << endl; } Foo(const Foo&) {
cout << "Foo copy ctor" << endl; } void operator=(const Foo&) {
cout << "Foo operator=" << endl; } ~Foo() {
cout << "Foo dtor" << endl; }}; Foo make_foo() {
//return Foo(); Foo f;//这里调用构造函数 return f;//若没有RVO优化,这里会调用拷贝构造函数 //若有RVO优化,则会将对象f直接返回回去,不需要再拷贝构造,相当于对象f提升了,提升成不是一个局部对象,return时它不会释放的} int main(void){
make_foo(); return 0;}
  • 测试
    在这里插入图片描述
    使用vs2008 debug编译运行
    在这里插入图片描述
    在这里插入图片描述
    使用vs2008 release编译运行
    在这里插入图片描述

在这里插入图片描述

  • eg测试:28\jmuduo\tests\Reactor_test04.cc
    28\jmuduo\tests\CMakeLists.txt
  • 测试:
    ./build clean可以清空以前的编译文件
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    直到打印20次时,g_loop->quit(),则这里的loop.loop();也就退出来了
    在这里插入图片描述

转载地址:http://amiws.baihongyu.com/

你可能感兴趣的文章
解决安装gevnet失败
查看>>
关于shell文件中出现syntax error: unexpected end of file
查看>>
git 的cherry-pick应用
查看>>
Linux命令英文全称
查看>>
Django学习之----model(1)
查看>>
Django学习之----model(2)
查看>>
推荐一下django学习的网址!!!
查看>>
git 使用小技巧之撤销提交操作与恢复更改前操作
查看>>
git 基础版
查看>>
git 撤销修改篇
查看>>
果汁带你学linux(01)
查看>>
django 自带页面缓存cache_page的使用及清除
查看>>
django cache的简单使用
查看>>
ping、traceroute、host、curl以及wget
查看>>
git merge 时可能会遇到的问题
查看>>
淘宝 OAuth2.0 的登录验证与授权
查看>>
git stash 使用技巧
查看>>
nginx 中location和root,你确定真的明白他们关系?
查看>>
一篇文章精通常用 git 命令
查看>>
Nginx配置文件nginx.conf 总结
查看>>