当前位置: 迅达文档网 > 党团工作 >

嵌入式操作系统内核原理和开发(线程状态)

| 来源:网友投稿

  嵌入式操作系统内核原理和开发(线程状态)

  从第一篇的 os 博客以来,谈了很多内容,有中断、切换、调度、内存、互斥和延时等等,但是线程的状态却没有涉及到,今天我们要好好说一说。说到线程的状态,按照一般的说法,主要包括就绪、延时、阻塞、阻塞超时四个状态。如果线程没有死亡的话,那么这几个状态也够用了,但是我们后来发现可能需要对某些线程进行挂起处理,这可能是出现了故障或者是为了调试使用。因此,除了上面的四个状态,我们还要补充对应的四个挂起状态,分别是挂起、延时挂起、阻塞挂起、阻塞延时挂起。

  说到了线程状态,下面我们就看看常见的线程处理函数有哪些,无外乎线程创建、线程延时、线程挂起、线程恢复和线程删除等等。

 [cpp] view plaincopy  RAW_U16 raw_task_create(RAW_TASK_OBJ

 *task_obj, RAW_U8

 *task_name,

 RAW_VOID

  *task_arg,

 

 RAW_U8

 task_prio,

 RAW_U16

 time_slice,

 PORT_STACK

 *task_stack_base,

 

 RAW_U32 stack_size, RAW_TASK_ENTRY task_entry, RAW_U8 auto_start)

  

  {

  

  #if (RAW_TASK_STACK_CHECK > 0)

  

  PORT_STACK

 *p_stack;

  

  RAW_U32 i;

  

  #endif

  

  RAW_SR_ALLOC();

  

  #if (RAW_TASK_FUNCTION_CHECK > 0)

  

  if (task_obj == 0) {

  

  return RAW_NULL_OBJECT;

  

  }

  

  if (task_prio >= CONFIG_RAW_PRIO_MAX) {

  

  return RAW_BYOND_MAX_PRIORITY;

  

  }

  

  if (task_stack_base == 0) {

  

  return RAW_NULL_POINTER;

  

  }

  

  if (task_entry == 0) {

  

  return RAW_NULL_POINTER;

  

  }

  

  #endif

  

  RAW_CRITICAL_ENTER();

  

 if (task_prio == IDLE_PRIORITY) {

  

  if (idle_task_exit) {

  

  RAW_CRITICAL_EXIT();

 

  return RAW_IDLE_EXIT;

  

  }

  

  idle_task_exit = 1;

  

  }

  

  RAW_CRITICAL_EXIT();

  

  raw_memset(task_obj, 0, sizeof(RAW_TASK_OBJ));

  

  #if (CONFIG_ROUND_ROBIN > 0)

  

  if (time_slice) {

  

  task_obj->time_total

 = time_slice;

  

  }

  

  else

 {

  

  task_obj->time_total

 = TIME_SLICE_DEFAULT;

  

  }

  

  task_obj->time_slice = task_obj->time_total;

  

  #endif

  

  if (auto_start)

  

  task_obj->task_state = RAW_RDY;

  

  else

  

  task_obj->task_state = RAW_SUSPENDED;

  

  #if (RAW_TASK_STACK_CHECK > 0)

  

  task_obj->task_stack_base = task_stack_base;

  

  p_stack = task_stack_base;

  

  for (i = 0; i < stack_size; i++) {

 

  *p_stack++ =0;

  

  }

  

  #endif

  

  task_obj->task_stack

 = port_stack_init(task_stack_base, stack_size, task_arg, task_entry);

  

  task_obj->task_name

  = task_name;

 

  task_obj->priority

 = task_prio;

  

  task_create_hook(task_obj);

  

  RAW_CRITICAL_ENTER();

  

  #if (RAW_TASK_STACK_CHECK > 0)

  

  task_obj->stack_size = stack_size;

  

  list_insert(&task_head, &task_obj->stack_check_list);

  

  #endif

  

  if (auto_start) {

  

  add_ready_list_end(&raw_ready_queue, task_obj);

  

  }

  

  if (raw_os_active !=

 RAW_OS_RUNNING) {

  /* Return if multitasking has not started

  */

  

  RAW_CRITICAL_EXIT();

  

  return RAW_OS_STOPPED;

  

  }

 

  RAW_CRITICAL_EXIT();

  

  if (auto_start) {

  

  raw_sched();

  

  }

  

  return RAW_SUCCESS;

  

  }

  创建线程的函数是比较复杂的,内容长一些,参数也多一些。首先看看有哪些参数,虽然很多,但是慢慢梳理一下也不难理解,有名称、参数、优先级、时间片、堆栈起始指针、堆栈大小、入口函数和标志。整个函数基本上都是赋值的过程,最重要的其实就两个部分,一个是 port_stack_init,另一个就是 add_ready_list_end。前者可以对堆栈进行默认处理,比如压入一些寄存器、压入函数参数、函数指针等等,后者就是把线程加入到就绪队列。

 [cpp] view plaincopy  RAW_U16

 raw_sleep(RAW_U32

 dly)

 

  {

  

  RAW_U16 error_status;

  

  RAW_SR_ALLOC();

  

  #if (RAW_TASK_FUNCTION_CHECK > 0)

  

  if (raw_int_nesting) {

  

  return RAW_NOT_CALLED_BY_ISR;

  

  }

  

  #endif

  

  RAW_CRITICAL_ENTER();

  

  if

 (dly) {

  

  /*system is locked so task can not sleep just return immediately*/

  

  if (raw_sched_lock) {

 

  RAW_CRITICAL_EXIT();

  

  return RAW_SCHED_DISABLE;

  

  }

  

  raw_task_active->task_state = RAW_DLY;

  

  tick_list_insert(raw_task_active, dly);

  

  remove_ready_list(&raw_ready_queue, raw_task_active);

  

  }

  

  else {

  

  /*make current task to the end of ready list*/

  

 move_to_ready_list_end(&raw_ready_queue, raw_task_active);

  

  }

  

  RAW_CRITICAL_EXIT();

  

  raw_sched();

 

  if (dly) {

  

  /*task is timeout after sleep*/

  

  error_status = block_state_post_process(raw_task_active, 0);

  

  }

  

  else {

  

  error_status = RAW_SUCCESS;

 

  }

  

  return error_status;

  

  }

  我们之前也介绍过系统的延时功能。延时,就是把线程暂时从就绪队列清除出来,添加到延时队列中。当然如果参数为0,那表示作者只是希望暂时释放 cpu 的使用权,如果此时没有同等优先级的任务,那么下一个运行的线程还是它自己。

 [cpp] view plaincopy  RAW_U16

 raw_task_suspend(RAW_TASK_OBJ *task_ptr)

  

  {

  

  RAW_SR_ALLOC();

  

  #if (RAW_TASK_FUNCTION_CHECK > 0)

  

  if (task_ptr == 0) {

  

  return RAW_NULL_OBJECT;

  

  }

  

  #endif

  

  if (task_ptr->priority == IDLE_PRIORITY) {

  

  return RAW_SUSPEND_TASK_NOT_ALLOWED;

  

  }

  

  RAW_CRITICAL_ENTER();

  

  if (task_ptr == raw_task_active) {

  

  if (raw_sched_lock) {

  

  RAW_CRITICAL_EXIT();

  

  return RAW_SCHED_LOCKED;

  

  }

  

  }

  

  switch (task_ptr->task_state) {

  

  case RAW_RDY:

  

  task_ptr->task_state

 =

 RAW_SUSPENDED;

  

  remove_ready_list(&raw_ready_queue, task_ptr);

  

  break;

  

  case RAW_DLY:

  

  task_ptr->task_state

 = RAW_DLY_SUSPENDED;

  

  break;

  

  case RAW_PEND:

  

  task_ptr->task_state

 = RAW_PEND_SUSPENDED;

  

  break;

  

  case RAW_PEND_TIMEOUT:

  

  task_ptr->task_state

 = RAW_PEND_TIMEOUT_SUSPENDED;

  

  break;

  

  case RAW_DLY_SUSPENDED:

  

  case RAW_PEND_SUSPENDED:

  

  case RAW_PEND_TIMEOUT_SUSPENDED:

  

  RAW_CRITICAL_EXIT();

  

  return RAW_SUSPENDED_AGAIN;

  

  default:

  

  #if (CONFIG_RAW_ASSERT > 0)

  

  RAW_ASSERT(0);

 

  #endif

  

  RAW_CRITICAL_EXIT();

  

  return

 RAW_STATE_UNKNOWN;

  

  }

  

  RAW_CRITICAL_EXIT();

  

  raw_sched();

 

  return RAW_SUCCESS;

  

  }

  挂起任务的动作其实是比较残暴的,因为此时你不知道线程处于什么状态。当然任务如果已经被挂起了,那什么也不用做了,否则就需要把任务修改为对应的挂起状态就可以了。当然如果任务是就绪态的,还得把任务清除处理来。在函数结束的时候,我们需要重新进行调度,因为很有可能当前最高优先级的线程已经发生了改变。

 [cpp] view plaincopy  RAW_U16

 raw_task_resume(RAW_TASK_OBJ *task_ptr)

  

  {

  

  RAW_SR_ALLOC();

  

  #if (RAW_TASK_FUNCTION_CHECK > 0)

  

  if (task_ptr == 0) {

  

  return RAW_NULL_OBJECT;

  

  }

  

  #endif

  

  RAW_CRITICAL_ENTER();

  

  switch (task_ptr->task_state) {

  

  case RAW_RDY:

  

  case RAW_DLY:

  

  case RAW_PEND:

  

  case RAW_PEND_TIMEOUT:

  

  RAW_CRITICAL_EXIT();

  

  return HAS_NOT_SUSPENDED;

  

  case RAW_SUSPENDED:

  

  task_ptr->task_state = RAW_RDY;

  

  add_ready_list(&raw_ready_queue, task_ptr);

  

  break;

  

  case RAW_DLY_SUSPENDED:

  

  task_ptr->task_state = RAW_DLY;

  

  break;

  

  case RAW_PEND_SUSPENDED:

  

  task_ptr->task_state = RAW_PEND;

  

  break;

  

  case RAW_PEND_TIMEOUT_SUSPENDED:

  

  task_ptr->task_state = RAW_PEND_TIMEOUT;

  

  break;

  

  default:

  

  #if (CONFIG_RAW_ASSERT > 0)

 

  RAW_ASSERT(0);

  

  #endif

  

  RAW_CRITICAL_EXIT();

  

  return RAW_STATE_UNKNOWN;

  

  }

  

  RAW_CRITICAL_EXIT();

  

  raw_sched();

 

  return RAW_SUCCESS;

  

  }

  恢复函数其实就是挂起函数的逆向操作。如果任务没有被挂起,那么什么也不用做。否则就需要把任务的状态修改为对应的非挂起状态,当然该就绪的线程还得加入到就绪队列当中去。同时在函数结束之前不忘调度一下,说不定刚刚释放的这个线程就是优先级最高的那个线程。

 [cpp] view plaincopy  RAW_U16 raw_task_delete(RAW_TASK_OBJ *task_ptr)

  

 {

  

  RAW_SR_ALLOC();

  

  #if (RAW_TASK_FUNCTION_CHECK > 0)

  

  if (task_ptr == 0) {

  

  return RAW_NULL_OBJECT;

  

  }

  

  if (raw_int_nesting) {

  

  return RAW_NOT_CALLED_BY_ISR;

  

  }

  

  #endif

  

  if (task_ptr->priority == IDLE_PRIORITY) {

  

  return RAW_DELETE_TASK_NOT_ALLOWED;

  

  }

  

  RAW_CRITICAL_ENTER();

  

  if (task_ptr == raw_task_active) {

  

  if (raw_sched_lock) {

  

  RAW_CRITICAL_EXIT();

  

  return RAW_SCHED_LOCKED;

  

  }

  

  }

  

  switch (task_ptr->task_state) {

  

  case RAW_RDY:

  

  remove_ready_list(&raw_ready_queue, task_ptr);

  

  break;

  

  case RAW_SUSPENDED:

  

  break;

  

  case RAW_DLY:

  /* Task is only delayed, not on any wait list

  */

  

  case RAW_DLY_SUSPENDED:

 

  tick_list_remove(task_ptr);

  

  break;

  

  case RAW_PEND:

  

  case RAW_PEND_SUSPENDED:

  

  case RAW_PEND_TIMEOUT:

  

  case RAW_PEND_TIMEOUT_SUSPENDED:

  

  tick_list_remove(task_ptr);

  

  list_delete(&task_ptr->task_list);

  

  break;

  

  default:

  

  #if (CONFIG_RAW_ASSERT > 0)

  

  RAW_ASSERT(0);

  

  #endif

  

  RAW_CRITICAL_EXIT();

  

  return

 RAW_STATE_UNKNOWN;

  

  }

  

  task_ptr->task_state = RAW_DELETED;

 

  #if (RAW_TASK_STACK_CHECK > 0)

  

  /*make after_delete_list to right position*/

  

  after_delete_list = task_ptr->stack_check_list.next;

  

  if (after_delete_list == &task_head) {

  

  after_delete_list = task_head.next;

  

  }

  

  list_delete(&task_ptr->stack_check_list);

  

  #endif

  

  RAW_CRITICAL_EXIT();

  

  raw_sched();

 

  return RAW_SUCCESS;

  

 }

  删除函数的动作其实是比较残忍的,因为此时你不清楚线程已经执行到哪一步了,拥有了那些资源,正在处理哪些资源,所以没事不要用这个函数。这里做的只是把任务从就绪队列、等待队列和阻塞队列清除出来,但是真正善后的工作要比这多得多,如果有兴趣,你看看 linux 的 exit 函数就明白了。

推荐访问:线程 内核 嵌入式

热门排行

党委党组落实全面从严治党主体责任规定指出本地区本单位发生重大违纪违法案件14篇

党委党组落实全面从严治党主体责任规定指出本地区本单位发生重大违纪违法案件14篇党委党组落实全面从严治党主体责任规定指出本地区本单位发生重大违纪违法案件篇1我

2022年五星支部创建实施方案5篇

2022年五星支部创建实施方案5篇2022年五星支部创建实施方案篇1为切实提高支部党建工作科学化水平、不断夯实党建基础,挖掘支部党建特色,创新支部党建工作做

七言绝句古诗精选【十首】

【 能力训练 导语】七言绝句是中国传统诗歌的一种体裁,简称七绝,属于近体诗范畴。此体全诗四句,每句七

2022年支部党员大会记录内容14篇

2022年支部党员大会记录内容14篇2022年支部党员大会记录内容篇120xx年度我校新党员发展工作已经开始。根据学校党委3月21日会议精神,今年新党员发展

统计工作如何为企业管理服务

作为企业管理重要组成部分的统计工作,在企业的经济运行中发挥着信息、咨询和监督三大作用,它为企业的经营

乡镇创建无毒社区工作方案

一、指导思想以“三个代表”重要思想为指导,认真贯彻落实上级精神,以禁吸戒毒为中心,全面落实禁毒工作责

四年级我家菜园日记500字

菜园子,就是种菜的地方。种菜的时候为了防止家禽进入菜地,于是农夫用篱笆或者栅栏将菜地围起来形成的一个

哈尔移动城堡电影观后有感范本

在观看完一部作品以后,相信你会有不少感想吧,这时我们很有必要写一篇观后感了。可能你现在毫无头绪吧,下

党支部2022年学习计划14篇

党支部2022年学习计划14篇党支部2022年学习计划篇1认真坚持“三会一课”制度,对于加强支部建设,提高党的战斗力、健全党的生活,严格党员管理,充分发挥党