当前位置:   article > 正文

百度自动驾驶apollo源码解读6:/cyber/croutine 模块_apollo croutine

apollo croutine

本篇解读一下/cyber/croutine模块,该模块文件比较少,detail文件夹,CRoutine类,RoutineFactory模板类


1.detail文件夹

主要实现类似linux下的ucontext_t结构和其四个关联函数getcontext、setcontext、makecontext、swapcontext.实现堆栈的创建保存和切换,为什么不使用linux自带api而是要自己用汇编实现呢?有博主文章说linux那一套api最终要牵扯到系统内核里面,cyber自己实现这一套完全是应用层的,可以进一步提高线程的切换和执行效率。有一说一他这一套写的牵涉到知识点还是满深的,看了两天也搜了下其他博主的讲解,现在还是不怎么理解,先做个记录,后期理解了补充上。


2.CRoutine类。

首先声明一个枚举类型,用state_成员储存该类型,表示协程可以处于哪些状态,READY, FINISHED, SLEEP, IO_WAIT, DATA_WAIT,CRoutine构造函数会将协程置于READY状态,提供公开函数set_state设置该状态,state函数获取该状态,UpdateState更新该状态,比如进入SLEEP状态之后,该函数会检测睡眠时间是不是到了,到了之后把状态设置为READY;如果线程出去DATA_WAIT或者IO_WAIT,并且updated_状态已经被设置了(意思相关数据已被更新了),就把状态设置为READY。UpdateState唯一的调用者,协程调度器利用NextRoutine调度到了自己之后调用UpdateState。下面列举一下CRoutine常规属性和对应的接口以及属性的作用和目的:

name_属性:获取接口name(),设置接口set_name()
注解:协程名字

id_属性:获取接口id(),设置接口set_id()
注解:协程ID,根据名字哈希值生成的整数

state_属性:获取接口state(),设置接口set_state()
注解:当前状态属性,Wake()、HangUp()、Sleep()、Resume()、UpdateState()等接口都会牵涉到该属性的操作

processor_id_属性:获取接口processor_id(),设置接口set_processor_id()
注解:协程所在Processor的编号,classic调度模式的时候该值为-1,意为不绑定任何Processor,choreography调度模式的时候该值为具体的Processor编号

priority_属性:获取接口priority(),设置接口set_priority()
注解:协程优先级,取值为0-20

group_name_属性:获取接口group_name(),设置接口set_group_name()
注解:协程所在分组名字,只有classic调度模式有分组模式,choreography调度模式没有

wake_time_属性:获取接口wake_time(),设置接口Sleep()
注解:休眠觉醒时间点,Sleep的时候进行设置,UpdateState不停的检测是否到点了

func_属性:获取接口 ,设置接口 
注解:协程执行体,构造函数的时候赋值,Run()函数的时候执行

context_属性:获取接口GetContext(),设置接口 
注解:构造函数的时候赋值,并利用MakeContext将context_和当前CRoutine进行相关绑定。包含协程堆栈属性,切换协程的时候就是切换堆栈,

lock_属性:获取接口 ,设置接口 
注解:协程锁,Acquire()接口获取锁资源,Release()接口释放锁资源,协程被Acquire()之后再次被Acquire()会失败

updated_属性:获取接口 ,设置接口SetUpdateFlag()
注解:数据更新标识,调用SetUpdateFlag代表以更新,UpdateState()会检测该标识

force_stop_属性:获取接口 ,设置接口Stop()
注解:强制停止表示,利用Stop接口设置,每次Resume的时候检测该标识

current_routine_属性:获取接口GetCurrentRoutine(),设置接口Resume()
注解:thread_local变量,意为线程是协程的容器,可能一个线程上面运行着很多协程,current_routine_指针用来标识线程运行的当前协程是哪一个
      Resume()函数会设置该值

main_stack_属性:获取接口GetMainStack() ,设置接口 
注解:主堆栈地址,固定值:nullptr。附注:Resume函数会调用SwapContext,将main_stack_和目标协程的stack进行切换,SwapContext暗含一个意思就是运行协程的执行体(即函数)
     SwapContext是一个同步操作,会运行完该协程(暗含最后自己yield)或者遇见协程由于其他原因进行yield操作

3.RoutineFactory模板类

确切的说不是模板类,是一个RoutineFactory类和5个模板函数CreateRoutineFactory,这5个模板函数的主要区别是数据类型占位符个数不同,1至5个,前N个代表数据,最后一个代面一个函数,如果仅有函数,此函数就是将来协程的执行体;如果有数据类型,则将来创建出来的协程执行体如下:有一个四循环,先把协程置于DATA_WAIT状态,同步获取数据,用传入的函数处理数据,设置协程状态为READY,协程进行yield。具体使用场景为1.task模块中的TaskManager::Enqueue.  2.component组件

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号