嵌入式操作系统内核原理和开发(事件)

发表于:2012-9-24 09:59

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:feixiaoxing    来源:51Testing软件测试网采编

  在很多操作系统的书上,其实互斥和同步是放在一起进行介绍的。互斥,比较简单,就是对某一份资源或者几份资源进行抢占获取。而同步是什么意思呢,就是某一个线程等待另外一个线程的通知,只有收到了通知,它才会去干某些事情。

  通常情况下,如果是抢占的话,那么两个人使用的必须是同一个锁,而同步的话,则需要好几个锁,因为一般情况下大家等待的东西都是不一样的,所以好几个锁是不可避免的。那么,有没有什么办法,可以用一个锁实现几个事情的并发和同步呢?这就是我们今天所要说的事件。可以从一个例子说明一下。

  比方说,我们现在打算进行八宝饭的烹饪。那么,在此之前需要进行各个辅料的准备工作,等到这些辅料都准备好了,就可以开始煮八宝饭了。因为辅料之间是相互独立的,所以完全可以分开独立完成,而在所有辅料都没有完成之前,我们只能等待。等到材料全部准备好,我们就可以开始烹饪的工作了。当然,在烹饪的时候,我们又可以准备进行下一轮工作了,也就是说进行下一次八宝饭的辅料准备。在这个地方,辅料的准备是由各个子线程完成的,而煮饭这个工作是主线程完成的,主线程和子线程之间就是通过事件进行沟通的。主线程需要知道当前各个材料准备好了没,而子线程需要知道八宝饭烧好了没,是不是该进行下一轮辅料的准备了。这个中间就存在一个同步的问题了。

  如果大家对之前的信号量还有印象的话,当初我们是用count来表示资源的个数。而今天,我们用flags来表示事件状态,而其中的bit则表示了一个一个具体的事件。只不过有的线程在等待多个事件,而有的线程在等待一个事件,有的线程在获取事件后bit位立即清除,有的线程在获取事件后继续留存。

  所以下面,我们就看看raw-os上面的事件是怎么设计的。当然,我们首先看到的还是关于事件的基本数据结构,

typedef struct RAW_EVENT
 {
  RAW_COMMON_BLOCK_OBJECT       common_block_obj;
  RAW_U32  flags;
  
 } RAW_EVENT;
 
 

  这和我们之前介绍的没什么不一样,就是通用结构加上flag标志。关于事件的基本处理函数也不复杂,主要就是创建、申请、设置和删除四个基本操作。我们来看看每一步分别是怎么实现的,首先介绍的还是事件的创建过程,

RAW_U16 raw_event_create(RAW_EVENT *event_ptr, RAW_U8 *name_ptr, RAW_U32 flags_init)
 {
  #if (RAW_EVENT_FUNCTION_CHECK > 0)
  
  if (event_ptr == 0) {
   
   return RAW_NULL_OBJECT;
  }
  
  #endif
 
  /*Init the list*/
  list_init(&event_ptr->common_block_obj.block_list);
  event_ptr->common_block_obj.block_way = 0;
  event_ptr->common_block_obj.name = name_ptr; 
  event_ptr->flags = flags_init ;
  
  return RAW_SUCCESS;
 }
 

  看了代码,相信要说的部分不是很多,关键就是flags的赋值部分,其他的都和信号量差不太多。这里的flags代表了某一个起始状态,也就是说当前可以干什么事情、满足哪些条件等等。下面,我们继续看事件的获取函数,稍微复杂一些,

RAW_U16 raw_event_get(RAW_EVENT *event_ptr, RAW_U32  requested_flags, RAW_U8 get_option, RAW_U32 wait_option)
 {
     RAW_U16 error_status;
   
     RAW_U8 status;
  RAW_SR_ALLOC();
 
  #if (RAW_EVENT_FUNCTION_CHECK > 0)
 
  if (raw_int_nesting) {
 
   return RAW_NOT_CALLED_BY_ISR;
   
  }
 
  if ((get_option  != RAW_AND) && (get_option  != RAW_OR) && (get_option  != RAW_AND_CLEAR) && (get_option  != RAW_OR_CLEAR)) {
 
   return RAW_NO_THIS_OPTION;
  }
  
  #endif
  
     RAW_CRITICAL_ENTER();
 
  /*if option is and flag*/
     if (get_option & RAW_FLAGS_AND_MASK) {
   
         if ((event_ptr->flags & requested_flags) == requested_flags) {
    
             status = RAW_TRUE;
         }
     
         else {
             status =  RAW_FALSE;
         }
     
     }
  /*if option is or flag*/
     else {
    
         if (event_ptr->flags & requested_flags) {
 
           
             status =  RAW_TRUE;
         }
     
         else {
 
             status =  RAW_FALSE;
         }
     
     }
 
 
   
     if (status) {
 
   /*does it need to clear the flags*/
   if (get_option & RAW_FLAGS_CLEAR_MASK) {
    event_ptr->flags  &=  ~requested_flags;
   }
   
   RAW_CRITICAL_EXIT(); 
   return RAW_SUCCESS;
               
     }
   
  /*Cann't get event, and return immediately if wait_option is  RAW_NO_WAIT*/
  if (wait_option == RAW_NO_WAIT) {
   RAW_CRITICAL_EXIT();
   return RAW_NO_PEND_WAIT;
  }  
 
  /*system is locked so task can not be blocked just return immediately*/
  if (raw_sched_lock) {  
   RAW_CRITICAL_EXIT(); 
   return RAW_SCHED_DISABLE;
  }
 
    /*Remember the passed information*/
  raw_task_active->raw_suspend_option =  get_option;
  raw_task_active->raw_suspend_flags = requested_flags;
  
  raw_pend_object(&event_ptr->common_block_obj, raw_task_active, wait_option);
  RAW_CRITICAL_EXIT();
 
  raw_sched();
  
  RAW_CRITICAL_ENTER();
  
  /*does it need to clear the flags*/
  if (get_option & RAW_FLAGS_CLEAR_MASK) {
   event_ptr->flags  &=  ~requested_flags;
  }
  
  RAW_CRITICAL_EXIT();
  
  /*So the task is waked up, need know which reason cause wake up.*/
  error_status = block_state_post_process(raw_task_active, 0);
  return error_status;
 
  
 }
 

31/3123>
《2023软件测试行业现状调查报告》独家发布~

精彩评论

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号