Ctrl-Z
一个多线程机器人运动控制强化学习部署框架
载入中...
搜索中...
未找到
z::AbstractScheduler< CTS > 模板类 参考

AbstractScheduler 调度器类型,用于管理任务,工作线程和数据。 更多...

#include <AbstractScheduler.hpp>

类 z::AbstractScheduler< CTS > 继承关系图:
z::AbstractScheduler< CTS > 的协作图:

struct  TCB
 Task Control Block 更多...
 

Public 类型

using Ptr = std::shared_ptr<AbstractScheduler<CTS...>>
 调度器类型的指针类型
 

Public 成员函数

 AbstractScheduler (const nlohmann::json &cfg=nlohmann::json())
 创建一个调度器
 
virtual ~AbstractScheduler ()
 销毁调度器
 
template<class ptr, typename ... Args>
ptr * CreateWorker (Args &&... args)
 从调度器创建一个Worker
 
void Start ()
 启动调度器
 
void Stop ()
 停止调度器,注意停止后无法再次启动调度器,必须重新创建调度器。
 
void SpinOnce ()
 进行一次调度,调度器将调度主线程任务(MainThreadTask)中的Worker,并为其他任务队列运行一个新的周期。 如果任务运行过慢,调度器会打印一个警告信息。**请不要在Worker中或者其他线程中调用这个函数,这个函数应该在主线程中调用。 否则会出现未定义行为!**
 
void Spin ()
 进行连续任务调度。
 
size_t getTimeStamp ()
 获取时间辍。
 
double getSpinOnceTime ()
 获取调度器的时间步长
 
size_t CreateTaskList (const std::string &TaskName, size_t div, bool MainThreadTask=false)
 创建一个任务队列,在调度器启动时,Workers中的TaskCreate方法会被调用,用于初始化每个Worker。
 
void DestroyTaskList (const std::string &TaskName)
 删除一个任务队列。
 
bool EnableTaskList (const std::string &TaskName)
 设置任务列表的启用状态
 
bool DisableTaskList (const std::string &TaskName)
 设置任务列表的禁用状态
 
void AddWorker (const std::string &TaskName, WorkerType *worker)
 向任务中添加一个工人
 
void AddWorkers (const std::string &TaskName, std::vector< WorkerType * > workers)
 批量向任务中添加工人
 
template<CTString CT, typename T>
void SetData (const T &data)
 从数据中心中获取数据,并自动更新时间戳
 
template<CTString CT, typename T>
size_t GetData (T &data)
 从数据中心中获取数据
 
- Public 成员函数 继承自 z::ZObject
void PrintSplitLine (size_t length=60, char c='-')
 print a split line, default length is 60 and character is '-'
 

静态 Public 成员函数

static AbstractScheduler< CTS... >::Ptr Create (const nlohmann::json &cfg=nlohmann::json())
 

Protected 成员函数

void run_once (TCB *tcb)
 运行任务的一个调度周期
 
void run (const std::string &TaskName)
 运行任务
 
void CheckRuntimeFrequency ()
 
void PrintWelcomeMessage ()
 

Protected 属性

std::atomic< bool > CanSpin = false
 
std::thread::id threadId
 main thread id
 
std::map< std::string, TCB * > TaskList
 task list
 
TCBMainThreadTaskBlock = nullptr
 control block of the main thread task
 
std::string MainThreadTaskName
 main thread task name
 
std::atomic< size_t > TimeStamp
 time stamp
 
DataCenter< CTS... > dataCenter
 data center for storing data with time stamp
 
std::mutex SyncMutex
 task list sync mutex
 
std::condition_variable SyncLock
 task list sync lock variable
 
std::vector< WorkerType * > ManagedWorkers
 worker list, these workers are created by the scheduler and managed by the scheduler.
 
std::weak_ptr< AbstractScheduler< CTS... > > weak_ptr
 weak pointer to the scheduler, used for worker to access scheduler
 
double spin_dt = 0.001
 task list spin once time
 
double HistorySpinDt = 0
 
std::chrono::steady_clock::time_point last_time
 
bool CheckFrequency__ = true
 

详细描述

template<CTSPair ... CTS>
class z::AbstractScheduler< CTS >

AbstractScheduler 调度器类型,用于管理任务,工作线程和数据。

调度器类型是CtrlZ框架的核心类型之一,用于管理任务和工作线程,和工人类(Workers)负责执行每一个具体的任务不同, 调度器类型主要负责管理任务和工作线程。通过在调度器类型中创建任务队列(TaskList),并在这些任务队列中添加工作线程(Workers), 调度器类型可以实现多任务调度,每一个任务队列(TaskList)都有一个独立的线程,用于调度这个任务队列中的工作线程。在运行过程中,调度器会根据 任务流水线中Worker的顺序在每个流水线循环中依次调用Worker的TaskCycleBegin, TaskRun和TaskCycleEnd方法,在任务开始和结束的时候还会调用TaskCreate和TaskDestroy方法。 通过这些方法,工作线程可以在任务开始和结束的时候进行初始化和销毁工作,而在任务运行的时候进行具体的工作。 此外调度器还可以为不同的任务队列设置不同的调度周期,通过设置调度周期,可以实现不同任务队列的不同调度频率,从而实现不同任务队列的不同调度速度。 调度器分为主线程任务(MainThreadTask)和其他任务队列,主线程任务是一个特殊的任务队列,它是在主线程中运行的,而其他任务队列是在独立的线程中运行的。其他任务队列的频率 可以通过设置调度周期来调整,可以设置为主任务队列的整数倍分频(1/n),而主任务队列的频率是固定的,受spinOnce函数的调用频率控制。 调度器类型还可以管理数据管线(DataCenter),用于存储和获取数据,数据管线中的数据通过时间戳来进行读写数据,存储在数据中心中的数据 都是线程安全的,可以在任何线程中读写数据。同时时间辍的存在保证了数据的时序性。

模板参数
CTS用于数据中心的键-类型对。其中键是一个编译期字符串常量,类型是数据的类型,通常是一个数字或者一个array。 这些键-类型对用于标识数据中心中的数据,通过键可以获取对应的数据, 通过类型可以确定数据的类型。而且这些键-类型对是在编译期就确定的, 保证了数据的唯一性。具体的使用方法可以参考CTSPair类,CTString类和DataCenter类。

构造及析构函数说明

◆ ~AbstractScheduler()

template<CTSPair ... CTS>
virtual z::AbstractScheduler< CTS >::~AbstractScheduler ( )
inlinevirtual

销毁调度器

销毁调度器时将销毁所有的任务队列(TaskList)但不会销毁Worker,Worker的生命周期由调度器外部管理, 调度器只负责管理任务队列。销毁调度器时,调度器会停止所有的任务队列,并等待所有的任务队列线程结束,主线程任务(MainThreadTask)也会被销毁。

成员函数说明

◆ AddWorker()

template<CTSPair ... CTS>
void z::AbstractScheduler< CTS >::AddWorker ( const std::string & TaskName,
WorkerType * worker )
inline

向任务中添加一个工人

参数
TaskName任务名称
worker工人

◆ AddWorkers()

template<CTSPair ... CTS>
void z::AbstractScheduler< CTS >::AddWorkers ( const std::string & TaskName,
std::vector< WorkerType * > workers )
inline

批量向任务中添加工人

参数
TaskName任务名称
workers工人列表,列表顺序即为任务队列中工人调度的顺序

◆ CreateTaskList()

template<CTSPair ... CTS>
size_t z::AbstractScheduler< CTS >::CreateTaskList ( const std::string & TaskName,
size_t div,
bool MainThreadTask = false )
inline

创建一个任务队列,在调度器启动时,Workers中的TaskCreate方法会被调用,用于初始化每个Worker。

参数
TaskName任务名
div分频系数,用于控制任务的调度频率,任务的调度频率是主线程任务的1/div。如果是主线程任务,div将被忽略。
MainThreadTask是否是主线程任务。
返回
size_t 任务ID

◆ CreateWorker()

template<CTSPair ... CTS>
template<class ptr, typename ... Args>
ptr * z::AbstractScheduler< CTS >::CreateWorker ( Args &&... args)
inline

从调度器创建一个Worker

这个函数用于从调度器中创建一个Worker,并将其添加到调度器的ManagedWorkers列表中。 Worker的生命周期由调度器管理,调度器会在销毁时销毁所有的Worker。用户不需要手动销毁Worker。

模板参数
ptrWorker类型的指针类型,通常是一个继承自AbstractWorker的类型。
ArgsWorker的构造函数参数类型,可以是任意类型,通常是一些配置参数或者数据。
参数
argsWorker的构造函数参数,可以是任意类型,通常是一些配置参数或者数据。
返回
ptr* 返回创建的Worker指针,用户可以通过这个指针来访问Worker的成员函数和数据。

◆ DestroyTaskList()

template<CTSPair ... CTS>
void z::AbstractScheduler< CTS >::DestroyTaskList ( const std::string & TaskName)
inline

删除一个任务队列。

删除一个任务队列时,调度器会停止这个任务队列,并等待当前周期结束,然后销毁任务队列。 销毁时将依次调用Worker的TaskDestroy方法。注意主线程任务(MainThreadTask)不能被销毁。

参数
TaskName待销毁的任务名

◆ DisableTaskList()

template<CTSPair ... CTS>
bool z::AbstractScheduler< CTS >::DisableTaskList ( const std::string & TaskName)
inline

设置任务列表的禁用状态

该函数的作用与EnableTaskList函数相反。

参数
TaskName任务名称
返回
true 任务已禁用
false 任务未禁用(可能找不到任务)

◆ EnableTaskList()

template<CTSPair ... CTS>
bool z::AbstractScheduler< CTS >::EnableTaskList ( const std::string & TaskName)
inline

设置任务列表的启用状态

此函数用于设置任务的启用状态。如果任务被启用,调度器将根据分频设置为该任务进行调度。 如果任务被禁用,任务将不会被调度,并且会一直被阻塞,直到再次启用。 需要注意的是,主线程任务始终处于启用状态,不受此函数的影响。

参数
TaskName任务名称
返回
true 任务已启用
false 任务未启用(可能找不到任务)

◆ GetData()

template<CTSPair ... CTS>
template<CTString CT, typename T>
size_t z::AbstractScheduler< CTS >::GetData ( T & data)
inline

从数据中心中获取数据

模板参数
CT数据名称
T数据类型
参数
data数据
返回
size_t 数据的时间戳

◆ getSpinOnceTime()

template<CTSPair ... CTS>
double z::AbstractScheduler< CTS >::getSpinOnceTime ( )
inline

获取调度器的时间步长

调度器的时间步长是调度器是所有任务队列的基础调度间隔,也是MainTaskList的间隔。 这个间隔由配置文件设置,但实际调用频率和调度器的SpinOnce函数的调用频率有关。SpinOnce会检查 设置的时间步长是否和实际调用频率一致,如果不一致,会打印警告信息。

返回
double 调度器的时间步长(seconds)

◆ getTimeStamp()

template<CTSPair ... CTS>
size_t z::AbstractScheduler< CTS >::getTimeStamp ( )
inline

获取时间辍。

时间辍是CtrlZ框架中的一个重要概念,用于标识数据的时序性,时间辍是一个递增的整数,每次调用SpinOnce函数时,时间辍都会递增1, 不同的TaskList中的Worker可以通过时间辍来获取数据,通过时间辍可以保证数据的时序性。 时间辍与TaskList中的分频系数无关,仅与SpinOnce函数的调用频率有关。

返回
size_t 时间辍

◆ run()

template<CTSPair ... CTS>
void z::AbstractScheduler< CTS >::run ( const std::string & TaskName)
inlineprotected

运行任务

参数
TaskName任务名

◆ run_once()

template<CTSPair ... CTS>
void z::AbstractScheduler< CTS >::run_once ( TCB * tcb)
inlineprotected

运行任务的一个调度周期

在一个调度周期内,调度器将按照顺序调用任务中的工作者。工作者将按照它们被添加到任务中的顺序被调用。对于每个工作者,将依次调用TaskCycleBegin、TaskRun、TaskCycleEnd函数。

参数
tcb给定的任务控制块

◆ SetData()

template<CTSPair ... CTS>
template<CTString CT, typename T>
void z::AbstractScheduler< CTS >::SetData ( const T & data)
inline

从数据中心中获取数据,并自动更新时间戳

模板参数
CT数据名称
T数据类型
参数
data数据

◆ Start()

template<CTSPair ... CTS>
void z::AbstractScheduler< CTS >::Start ( )
inline

启动调度器

启动调度器时将启动所有的任务队列(TaskList)和主线程任务(MainThreadTask),启动任务队列时,调度器会调用任务队列中的Worker的TaskCreate方法, 用于初始化Worker。启动调度器后,调度器会开始调度任务队列中的Worker,调度器会根据任务队列中的调度周期来调度任务队列中的Worker, 调度周期是通过调度器的SpinOnce函数来控制的,SpinOnce函数会在主线程中调用,用于调度任务队列中的Worker,当任务队列中的Worker运行过慢时, 调度器会打印一个警告信息。

值得注意的是创建的非主线任务默认是不使能的,需要通过EnableTaskList函数来使能任务队列,使能任务队列后,任务队列中Worker的调度周期才会生效, 任务会在第一个Worker的TaskCycleBegin前被阻塞,直到任务队列被使能。然而在任务创建的时候,任务队列中的Worker会被调用一次TaskCreate方法, 用于初始化Worker,不受使能状态的影响。主线程任务(MainThreadTask)是默认使能的,不受使能状态的影响。


该类的文档由以下文件生成: