当前位置:   article > 正文

百度自动驾驶apollo源码解读23:/cyber/time模块和/cyber/timer模块_c++ cyber rate

c++ cyber rate

这两个都是和时间相关的模块,一起解读吧。

time模块

Time类:此类总结来讲就是封装了C++11的事件库操作,使得更简洁,C++11的又是什么steady_clock,又是什么system_clock,又是什么high_resolution_clock,又是什么epoch,又是什么Duration,繁琐复杂,使用起来没那么方便。而本类成员变量仅有一个int 64的数值来表示当前时间,支持时间加减比较运算,支持转化字符串,转为秒数、毫秒表示时间。支持睡眠到指定时间的操作。需要注意的是他有三个构造函数,不同数据类型代表不同的意思,uint64_t代表纳秒,int也代表纳秒,double代表秒。容易上手,值得推荐

Duration类:此类总结两件就是表示两个类时间差的,成员变量仅有一个int 64的数值来表示时间差,支持一系列的加减比价操作,使得Time类时间的计算更方便

Clock类:起初我以为这会是个类似steady_clock和system_clock的时钟,里面会有变量代表时间一直在走动,后来发现并不是这样,他的存在完全是为了阿波罗的仿真功能,使得想要当前几点就是几点

Rate类:这个类是为了控制帧率的,举个例子,有个任务要你向某个网站以固定100贞的帧率发送数据,你大概会这么写:先写一个while死循环,里面第一步就是发送数据,第二部就是sleep10毫秒呗,其实这是不准备的,因为没有考虑发送数据包这个操作也是需要消耗一定时间的,最后帧率会小于100贞,怎么才能准确的达到帧率呢,本类就是为这个设计的。需要注意的是他有三个构造函数,不同数据类型代表不同的意思,uint64_t代表纳秒,double代表秒。下面看个例子:

  1. #include <iostream>
  2. #include "cyber/examples/proto/examples.pb.h"
  3. #include "cyber/cyber.h"
  4. #include "cyber/time/rate.h"
  5. #include "cyber/time/time.h"
  6. using apollo::cyber::Rate;
  7. using apollo::cyber::Time;
  8. int64_t g_int = 0;
  9. // 运行耗时5毫秒,测时长代码
  10. // auto start = apollo::cyber::Time::Now();
  11. // run_cpu();
  12. // auto end = apollo::cyber::Time::Now();
  13. // auto dur = end - start;
  14. // std::cout << dur.ToSecond() << std::endl;
  15. void run_cpu() {
  16. for (int i = 0; i < 20 * 1024 * 1024; i++) {
  17. g_int += i * i;
  18. }
  19. }
  20. int main(int argc, char* argv[]) {
  21. apollo::cyber::Init(argv[0]);
  22. Rate r(50.0);
  23. std::cout << r.CycleTime() << std::endl;
  24. while (!apollo::cyber::IsShutdown()) {
  25. std::cout << apollo::cyber::Time::Now() << " " << r.CycleTime() << std::endl;
  26. run_cpu();
  27. r.Sleep();
  28. }
  29. return 0;
  30. }

看了上面的例子我们看下他是如何实现的,主要看他的Sleep接口,我画了一张图来表示里面各个变量的关系和代表的意思。

后来其实想想也没那么复杂,知道当前循环开始时间,知道想要的帧率即一次循环时间间隔,直接使用std::this_thread::sleep_until就可以定位到睡眠截止时间。

 timer模块

关于这个模块推荐两篇文章:

https://zhuanlan.zhihu.com/p/115990699
https://blog.csdn.net/xqjcool/article/details/127948825
我也是看了这两篇文章才有所理解,直接看代码,不懂他是的设计意图的话是真的难懂。

TimerTask结构体
timer_id_:定时器ID
callback:回调函数
interval_ms:触发间隔
remainder_interval_ms:除了大圈上的花费,小圈上剩余间隔时间
next_fire_duration_ms:下一次触发间隔时间(可能大于小圈一圈的时间)
accumulated_error_ns:累积的错误时间
last_execute_time_ns:上次执行的时间戳
mutex:定时器互斥体

TimerBucket类
一个封装Timer的线性容器,注意使用的是weak_ptr而不是shared_ptr,我想这个原因应该和我下面讲到的“一些难点和理解”中的第一个是一样的

Timer类
timer_id_属性:定时器ID
timer_opt_属性:定时器配置信息
timing_wheel_属性:轮子指针
task_属性:task指针,相比timer_opt_属性来讲多了一些成员,timer_opt_属性主要用于初始化,task_属性更多的记录定时器运行中各个属性
started_属性:是否开启
接口:
关于构造函数接口、析构函数接口、Start接口、Stop接口都比较容易理解,不再赘述。对InitTimerTask接口做一下分析,该接口主要用于初始化成员属性task_


TimingWheel类(注意这是一个单例类)
running_属性:是否仍然运行
tick_count_属性:类似时钟秒针,走了多少步
running_mutex_属性:和running_配套使用的互斥体
work_wheel_属性:小圈,类似秒针,轮到谁就会立即执行,每圈512个单位,每个单位都可能会有一串执行体
assistant_wheel_属性:大圈,类似分针,小圈转动一圈,改圈指针才会+1,每圈64个单位,轮到谁,会将改圈上的所有可执行体添加到小圈上面
current_work_wheel_index_属性:小圈指针
current_work_wheel_index_mutex_属性:小圈互斥体
current_assistant_wheel_index_属性:大圈指针
current_assistant_wheel_index_mutex_属性:大圈互斥体
tick_thread_属性:驱动时间走动的线程
Start接口:开启服务接口,由第一个调用AddTask接口的调用
Shutdown接口:停止服务接口,由单例模板析构调用
Tick接口:挨个取出小圈上的当前指针里面的执行体,并发执行,并将该执行体从小圈上去除
AddTask接口:将TimerTask添加到时间轮上,如果时间长度小于一圈就直接添加到小圈上面,否则就添加到大圈上面
Cascade接口:将当前大圈指针的位置任务添加到小圈上面,并从大圈上面移除
TickFunc接口:线程执行体,每走一次调用Tick一次,current_work_wheel_index_增加1,走够小圈一圈大圈增加1,并调用Cascade接口

一些难点和理解:

1.InitTimerTask里面为什么使用了weak_ptr?
因为要将这个指针传进一个lumbda表达式里面,这个lumbda和主线程不在同一个,本线程为主,lumbda线程为辅,为主的可能会随时销毁指针,为辅的是不确定时机的执行,执行的时候询问一下指针是否仍然有效好像shared_ptr的user_count也可以询问是不是有效的啊?是滴,但是如果传了shared_ptr主线程就不方便随时销毁指针了。这是我的理解,原作者的意图是不是这样的有待商榷。

2.TimerTask里面的mutex的作用
由于执行线程和task管理线程不在同一线程,防止执行的时候别人给销毁了

3.关于设计的评价
整体来看比较晦涩难懂,如果不是看了上述两篇文章,是很难理解这种设计和意图的,还有就是作者为了防止时间长度超过一整圈的长度,设计两个环,我个人觉得是不是在TimerTask里面增加一个变量,自己还有几圈就可以得到执行权了,每转一圈这个数字就减去1,直到此数字为0就立即执行,这个设计是不是更好理解一点呢,这么做有什么逻辑漏洞吗?各位大佬可以点评一下。

4.C++11自带时钟用法
system_clock:从系统获取时钟;是系统的时钟;因为系统的时钟可以修改;甚至可以网络对时; 所以用系统时间计算时间差可能不准
steady_clock:不能被修改的时钟;是单调的时钟,相当于教练手中的秒表;只会增长,适合用于记录程序耗时
high_resolution_clock:高精度时钟,实际上是system_clock或者steady_clock的别名,最小精度是纳秒

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/人工智能uu/article/detail/879245
推荐阅读
相关标签
  

闽ICP备14008679号