Orocos Activity&ExecutionEngine 解析
来源:互联网 发布:淘宝gxg官方店是真的吗 编辑:程序博客网 时间:2024/05/22 18:28
Orocos 每一个TaskContext 类表示一个完整的模块,该模块有configure,start,stop,clean,setPeriod等等方法来控制这个模块的运行。如果使用了该模块的 setActivity 方法,该模块将置于一个单独的线程中运行,根据自己的周期频率执行各个函数,读写dataport等。
setActivity 方法如下:
bool TaskContext::setActivity(ActivityInterface* new_act) // Activity 继承于 ActivityInterface{ if (this->isRunning()) return false; if ( new_act == 0) {#if defined(ORO_ACT_DEFAULT_SEQUENTIAL) new_act = new SequentialActivity();#elseif defined(ORO_ACT_DEFAULT_ACTIVITY) new_act = new Activity(); // 在这new了一个新的Activity,即创建了一个新的线程用于执行该模块。#endif } new_act->stop(); if(our_act){ our_act->stop(); } new_act->run( this->engine() ); // 这个模块所有需要运行的资源都是通过这个 ExecutionEngine 来执行的。 our_act = ActivityInterface::shared_ptr( new_act ); our_act->start(); return true;}
所以说,ExecutionEngine 是通过 Activity 来执行的,而 TaskContext 中的资源又是通过 ExecutionEngine 来执行的。归根到底是通过 Activity 来执行的 :)
其中每一个 Activity 类都表示一个线程:
class Activity : public base::ActivityInterface, public os::Thread
其中 os::Thread 类根据编译时所选择的平台可以是 gnulinux, xenomai, win32等线程的实现:
#ifdef OROPKG_OS_GNULINUX #include "gnulinux/fosi.h"#endif#ifdef OROPKG_OS_LXRT #include "lxrt/fosi.h"#endif#ifdef OROPKG_OS_XENOMAI #include "xenomai/fosi.h"#endif#ifdef OROPKG_OS_ECOS #include "ecos/fosi.h"#endif#ifdef OROPKG_OS_MACOSX #include "macosx/fosi.h"#endif#ifdef OROPKG_OS_WIN32 #include "win32/fosi.h"#endif
Thread 类结构如下:
class Thread: public ThreadInterface{ friend void* thread_function(void* t); // 传入Activity的this指针(其中又保存了一个ExecutionEngine的指针),thread_function中实现一个while(1){...}来运行各种Hook,从而驱动顶层的 TaskContext 的运转。public: Thread(int scheduler, int priority, double period, unsigned cpu_affinity, const std::string & name); // 根据条件构造相应的线程 virtual ~Thread(); bool setPeriod(Seconds s); // 执行周期,也可以为非周期性的 ...private: Thread(const Thread&); // noncopiable ...}
最关键的就是 thread_function 这个函数了,实现了线程的周期性执行,step执行等:
void *thread_function(void* t){ /** * This is one time initialisation */ Thread* task = static_cast<os::Thread*> (t); Logger::In in(task->getName()); task->configure(); // signal to setup() that we're created. rtos_sem_signal(&(task->sem)); // This lock forces setup(), which holds the lock, to continue. { MutexLock lock(task->breaker); }#ifdef OROPKG_OS_THREAD_SCOPE // order thread scope toggle bit on thread number unsigned int bit = task->threadNumber();#endif SCOPE_OFF int overruns = 0, cur_sched = task->msched_type; NANO_TIME cur_period = task->period; while (!task->prepareForExit) { TRY( /** * The real task starts here. */ while (1) { if (!task->active || (task->active && task->period == 0) || !task->running ) { // consider this the 'configuration or waiting for command state' if (task->period != 0) { overruns = 0; // drop out of periodic mode: rtos_task_set_period(task->getTask(), 0); } rtos_sem_wait(&(task->sem)); // wait for command. task->configure(); // check for reconfigure if (task->prepareForExit) // check for exit { break; // break while(1) {} } // end of configuration } // This is the running state. Only enter if a task is running if ( task->running ) { if (task->period != 0) // periodic { MutexLock lock(task->breaker); while(task->running && !task->prepareForExit ) { TRY ( SCOPE_ON task->step(); // one cycle SCOPE_OFF ) CATCH_ALL ( SCOPE_OFF throw; ) // Check changes in period if ( cur_period != task->period) { // reconfigure period before going to sleep rtos_task_set_period(task->getTask(), task->period); cur_period = task->period; if (cur_period == 0) break; // break while(task->running) if no longer periodic } // Check changes in scheduler if ( cur_sched != task->msched_type) { rtos_task_set_scheduler(task->getTask(), task->msched_type); cur_sched = task->msched_type; } // rtos_task_wait_period will return immediately if // the task is not periodic (ie period == 0) // return non-zero to indicate overrun. if (rtos_task_wait_period(task->getTask()) != 0) { ++overruns; if (overruns == task->maxOverRun) break; // break while(task->running) } else if (overruns != 0) --overruns; } // while(task->running) if (overruns == task->maxOverRun || task->prepareForExit) break; // break while(1) {} } else // non periodic: TRY ( // this mutex guarantees that stop() waits // until loop() returns. MutexLock lock(task->breaker); task->inloop = true; SCOPE_ON task->loop(); SCOPE_OFF task->inloop = false; ) CATCH_ALL ( SCOPE_OFF task->inloop = false; throw; ) } } // while(1) if (overruns == task->maxOverRun) { task->emergencyStop(); Logger::In in(rtos_task_get_name(task->getTask())); log(Critical) << rtos_task_get_name(task->getTask()) << " got too many periodic overruns in step() (" << overruns << " times), stopped Thread !" << endlog(); log() << " See Thread::setMaxOverrun() for info." << endlog(); } )CATCH(std::exception const& e, SCOPE_OFF task->emergencyStop(); Logger::In in(rtos_task_get_name(task->getTask())); log(Critical) << rtos_task_get_name(task->getTask()) << " caught a C++ exception, stopped thread !" << endlog(); log(Critical) << "exception was: " << e.what() << endlog(); ) CATCH_ALL ( SCOPE_OFF task->emergencyStop(); Logger::In in(rtos_task_get_name(task->getTask())); log(Critical) << rtos_task_get_name(task->getTask()) << " caught an unknown C++ exception, stopped thread !" << endlog(); ) } // while (!prepareForExit) return 0;}void Thread::emergencyStop(){ // set state to not running this->running = false; this->inloop = false; this->active = false; // execute finalize in current mode, even if hard. this->finalize();}
0 0
- Orocos Activity&ExecutionEngine 解析
- Orocos ExecutionEngine 对函数Operation调用的实现
- Orocos OperationCaller 解析
- Orocos DataPort 解析: orocos lock free data object
- Activity解析
- Activity解析
- Activity解析
- OROCOS 网上注释文档
- orocos 类型系统分析
- scrapy源码分析(八)--------ExecutionEngine
- 机器人开源项目:orocos
- orocos Logger 类的设计
- Activity 、Intent深入解析
- Activity 、Intent深入解析
- jbpm Activity深入解析
- 解析Activity、Intent、Service
- Activity Manager框架解析
- Activity 、Intent深入解析
- Node.js Express目录结构
- unity做陶艺(动态改变模型网格)
- UIScrollView的PageEnable可以实现slider
- Docker 入门教程(四)
- 字符数组与字符指针
- Orocos Activity&ExecutionEngine 解析
- linux基本命令(49)——at命令
- 有用的sleep(1)
- MAC下php出现:Call to undefined function Think\imagettftext()的解决办法
- Android 知名博客
- Mesh网格篇(一)代码生成圆柱Mesh
- iOS UIApplication功能
- 从零开始学shell(4)--命令行及处理
- org.hibernate.QueryException:Expected positional parameter count: 1