程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> rt-thread線程源碼分析

rt-thread線程源碼分析

編輯:C++入門知識

rt-thread操作系統是一個多線程的操作系統,線程對於rt-thread來說是一個很重要的概念,因此,必須掌握它。 1 線程控制塊的數據結構 [cpp]   /**   * Thread structure   */   struct rt_thread   {       /* rt object *///這裡就是rt_object的結構,其實也可以用rt_object parent來定義,估計線程在早些時候並沒有這麼做,後來也就沒改過來       char        name[RT_NAME_MAX];                      /**< the name of thread */       rt_uint8_t  type;                                   /**< type of object */       rt_uint8_t  flags;                                  /**< thread's flags */          #ifdef RT_USING_MODULE//模塊ID       void       *module_id;                              /**< id of application module */   #endif       //內核對象鏈表       rt_list_t   list;                                   /**< the object list */       rt_list_t   tlist;                                  /**< the thread list *///線程鏈表,一般用作就緒隊列元素節點          /* stack point and entry */       void       *sp;                                     /**< stack point *///棧指針       void       *entry;                                  /**< entry *///入口函數       void       *parameter;                              /**< parameter *///入口函數對應的參數       void       *stack_addr;                             /**< stack address *///棧地址       rt_uint16_t stack_size;                             /**< stack size *///棧大小          /* error code */       rt_err_t    error;                                  /**< error code *///錯誤代碼          rt_uint8_t  stat;                                   /**< thread stat *///線程的當前狀態          /* priority */       rt_uint8_t  current_priority;                       /**< current priority *///當前優先級       rt_uint8_t  init_priority;                          /**< initialized priority *///初始優先級   #if RT_THREAD_PRIORITY_MAX > 32       rt_uint8_t  number;       rt_uint8_t  high_mask;   #endif       rt_uint32_t number_mask;      #if defined(RT_USING_EVENT)//與IPC機制事件相關的一些參數       /* thread event */       rt_uint32_t event_set;       rt_uint8_t  event_info;   #endif          rt_ubase_t  init_tick;                              /**< thread's initialized tick *///初始tick       rt_ubase_t  remaining_tick;                         /**< remaining tick *///剩余tick          struct rt_timer thread_timer;                       /**< built-in thread timer *///線程定時器          void (*cleanup)(struct rt_thread *tid);             /**< cleanup function when thread exit *///相當於線程的析構函數,用於銷毀線程時做些後續操作          rt_uint32_t user_data;                              /**< private user data beyond this thread *///析構函數的輸入參數   };   typedef struct rt_thread *rt_thread_t;     2 線程創建及初始化 2.1 初始化線程 [cpp]   /*@{*/      /**   * This function will initialize a thread, normally it's used to initialize a   * static thread object.   *   * @param thread the static thread object   * @param name the name of thread, which shall be unique   * @param entry the entry function of thread   * @param parameter the parameter of thread enter function   * @param stack_start the start address of thread stack   * @param stack_size the size of thread stack   * @param priority the priority of thread   * @param tick the time slice if there are same priority thread   *   * @return the operation status, RT_EOK on OK, -RT_ERROR on error   */   rt_err_t rt_thread_init(struct rt_thread *thread,                           const char       *name,                           void (*entry)(void *parameter),                           void             *parameter,                           void             *stack_start,                           rt_uint32_t       stack_size,                           rt_uint8_t        priority,                           rt_uint32_t       tick)   {       /* thread check *///參數檢查       RT_ASSERT(thread != RT_NULL);       RT_ASSERT(stack_start != RT_NULL);          /* init thread object */       rt_object_init((rt_object_t)thread, RT_Object_Class_Thread, name);//初始化內核對象          return _rt_thread_init(thread,                              name,                              entry,                              parameter,                              stack_start,                              stack_size,                              priority,                              tick);   }   其中_rt_thread_init的函數如下定義: [cpp]   static rt_err_t _rt_thread_init(struct rt_thread *thread,                                   const char       *name,                                   void (*entry)(void *parameter),                                   void             *parameter,                                   void             *stack_start,                                   rt_uint32_t       stack_size,                                   rt_uint8_t        priority,                                   rt_uint32_t       tick)   {       /* init thread list */       rt_list_init(&(thread->tlist));//初始化線程節點          thread->entry = (void *)entry;//入口函數       thread->parameter = parameter;//入口函數的參數          /* stack init */       thread->stack_addr = stack_start;//棧地址       thread->stack_size = (rt_uint16_t)stack_size;//棧大小          /* init thread stack */       rt_memset(thread->stack_addr, '#', thread->stack_size);//將棧內的所有字節初始化為'#'號       thread->sp = (void *)rt_hw_stack_init(thread->entry, thread->parameter,//初始化時設置sp的內容,rt_hw_stack_init是一個與具體MCU相關的函數,這裡就不做介紹           (void *)((char *)thread->stack_addr + thread->stack_size - 4),           (void *)rt_thread_exit);          /* priority init */       RT_ASSERT(priority < RT_THREAD_PRIORITY_MAX);       thread->init_priority    = priority;//當前優先級和初始化優先級設置       thread->current_priority = priority;          /* tick init */       thread->init_tick      = tick;//初始化tick和剩余tick       thread->remaining_tick = tick;          /* error and flags */       thread->error = RT_EOK;//錯誤的狀態,線程狀態初始化時為RT_THREAD_INIT       thread->stat  = RT_THREAD_INIT;          /* initialize cleanup function and user data */       thread->cleanup   = 0;//線程析構函數及其參數       thread->user_data = 0;          /* init thread timer */       rt_timer_init(&(thread->thread_timer),//初始化線程的定時器                     thread->name,                     rt_thread_timeout,                     thread,                     0,                     RT_TIMER_FLAG_ONE_SHOT);          return RT_EOK;   }     其中rt_thread_timeout的函數如下定義: [cpp]  /**   * This function is the timeout function for thread, normally which is invoked   * when thread is timeout to wait some resource.   *   * @param parameter the parameter of thread timeout function   */   void rt_thread_timeout(void *parameter)   {       struct rt_thread *thread;          thread = (struct rt_thread *)parameter;          /* thread check */       RT_ASSERT(thread != RT_NULL);       RT_ASSERT(thread->stat == RT_THREAD_SUSPEND);          /* set error number */       thread->error = -RT_ETIMEOUT;          /* remove from suspend list *///從掛起鏈表中移除       rt_list_remove(&(thread->tlist));          /* insert to schedule ready list */       rt_schedule_insert_thread(thread);//加入調度器          /* do schedule */       rt_schedule();//重新調度   }       2.2 創建線程 [cpp]   /**   * This function will create a thread object and allocate thread object memory   * and stack.   *   * @param name the name of thread, which shall be unique   * @param entry the entry function of thread   * @param parameter the parameter of thread enter function   * @param stack_size the size of thread stack   * @param priority the priority of thread   * @param tick the time slice if there are same priority thread   *   * @return the created thread object   */   rt_thread_t rt_thread_create(const char *name,                                void (*entry)(void *parameter),                                void       *parameter,                                rt_uint32_t stack_size,                                rt_uint8_t  priority,                                rt_uint32_t tick)   {       struct rt_thread *thread;       void *stack_start;          thread = (struct rt_thread *)rt_object_allocate(RT_Object_Class_Thread,//動態分配一個內核對象                                                       name);       if (thread == RT_NULL)           return RT_NULL;          stack_start = (void *)rt_malloc(stack_size);//動態分配一個線程棧       if (stack_start == RT_NULL)       {           /* allocate stack failure */           rt_object_delete((rt_object_t)thread);              return RT_NULL;       }          _rt_thread_init(thread,//初始化線程                       name,                       entry,                       parameter,                       stack_start,                       stack_size,                       priority,                       tick);          return thread;   }     3 線程的脫離及刪除 3.1 脫離線程 [cpp]   /**   * This function will detach a thread. The thread object will be removed from   * thread queue and detached/deleted from system object management.   *   * @param thread the thread to be deleted   *   * @return the operation status, RT_EOK on OK, -RT_ERROR on error   */   rt_err_t rt_thread_detach(rt_thread_t thread)   {       rt_base_t lock;          /* thread check */       RT_ASSERT(thread != RT_NULL);          /* remove from schedule */       rt_schedule_remove_thread(thread);//將線程從調度器中移除          /* release thread timer */       rt_timer_detach(&(thread->thread_timer));//脫離定時器          /* change stat */       thread->stat = RT_THREAD_CLOSE;//將線程的狀態設置為RT_THREAD_CLOSE          /* detach object */       rt_object_detach((rt_object_t)thread);//脫離內核對象          if (thread->cleanup != RT_NULL)//如果存在線程析構函數       {           /* disable interrupt */           lock = rt_hw_interrupt_disable();//關中斷              /* insert to defunct thread list *///rt_thread_defunct鏈表在系統空閒時將被空閒線程來處理           rt_list_insert_after(&rt_thread_defunct, &(thread->tlist));//將線程加入到rt_thread_defunct鏈表中              /* enable interrupt */           rt_hw_interrupt_enable(lock);//開中斷       }          return RT_EOK;   }   3.2 刪除線程 [cpp]   /**   * This function will delete a thread. The thread object will be removed from   * thread queue and detached/deleted from system object management.   *   * @param thread the thread to be deleted   *   * @return the operation status, RT_EOK on OK, -RT_ERROR on error   */   rt_err_t rt_thread_delete(rt_thread_t thread)   {       rt_base_t lock;          /* thread check */       RT_ASSERT(thread != RT_NULL);          /* remove from schedule */       rt_schedule_remove_thread(thread);//從調度器中移除線程          /* release thread timer */       rt_timer_detach(&(thread->thread_timer));//脫離定時器          /* change stat */       thread->stat = RT_THREAD_CLOSE;//線程狀態設置為RT_THREAD_CLOSE          /* disable interrupt */       lock = rt_hw_interrupt_disable();//關中斷          /* insert to defunct thread list */       rt_list_insert_after(&rt_thread_defunct, &(thread->tlist));//將當前線程加入到空閒時才會處理的鏈表中          /* enable interrupt */       rt_hw_interrupt_enable(lock);//開中斷          return RT_EOK;   }   4 啟動線程 [cpp]  /**   * This function will start a thread and put it to system ready queue   *   * @param thread the thread to be started   *   * @return the operation status, RT_EOK on OK, -RT_ERROR on error   */   rt_err_t rt_thread_startup(rt_thread_t thread)   {       /* thread check *///參數檢查       RT_ASSERT(thread != RT_NULL);       RT_ASSERT(thread->stat == RT_THREAD_INIT);          /* set current priority to init priority */       thread->current_priority = thread->init_priority;//啟動線程時將線程當前的優先級設置為初始優先級          /* calculate priority attribute */   #if RT_THREAD_PRIORITY_MAX > 32       thread->number      = thread->current_priority >> 3;            /* 5bit */       thread->number_mask = 1L << thread->number;       thread->high_mask   = 1L << (thread->current_priority & 0x07);  /* 3bit */   #else       thread->number_mask = 1L << thread->current_priority;   #endif          RT_DEBUG_LOG(RT_DEBUG_THREAD, ("startup a thread:%s with priority:%d\n",                                      thread->name, thread->init_priority));       /* change thread stat */       thread->stat = RT_THREAD_SUSPEND;//將線程的狀態設置為RT_THREAD_SUSPEND       /* then resume it */       rt_thread_resume(thread);//還原線程       if (rt_thread_self() != RT_NULL)//如果當前的線程不為空,則執行線程調度操作       {           /* do a scheduling */           rt_schedule();       }          return RT_EOK;   }     其中rt_thread_self函數如下定義: [cpp]  /**   * This function will return self thread object   *   * @return the self thread object   */   rt_thread_t rt_thread_self(void)   {       return rt_current_thread;   }   rt_current_thread為全局變量,保存當前正在運行的線程。 rt_thread_resume函數見後第6章內容,rt_schedule函數見線程調度源碼分析相關章節. 5 線程掛起 [cpp]  /**   * This function will suspend the specified thread.   *   * @param thread the thread to be suspended   *   * @return the operation status, RT_EOK on OK, -RT_ERROR on error   *   * @note if suspend self thread, after this function call, the   * rt_schedule() must be invoked.   */   rt_err_t rt_thread_suspend(rt_thread_t thread)   {       register rt_base_t temp;          /* thread check */       RT_ASSERT(thread != RT_NULL);          RT_DEBUG_LOG(RT_DEBUG_THREAD, ("thread suspend:  %s\n", thread->name));          if (thread->stat != RT_THREAD_READY)//此函數只對處於就緒狀態的線程操作       {           RT_DEBUG_LOG(RT_DEBUG_THREAD, ("thread suspend: thread disorder, %d\n",                                          thread->stat));                      return -RT_ERROR;       }          /* disable interrupt */       temp = rt_hw_interrupt_disable();//關中斷          /* change thread stat */       thread->stat = RT_THREAD_SUSPEND;//將線程設置為掛起狀態       rt_schedule_remove_thread(thread);//將線程從調試器中移除          /* enable interrupt */       rt_hw_interrupt_enable(temp);//開中斷          return RT_EOK;   }     有關rt_schedule_remove_thread函數見後續在前調度器源碼分析的文章。 6 線程還原 [cpp]   /**   * This function will resume a thread and put it to system ready queue.   *   * @param thread the thread to be resumed   *   * @return the operation status, RT_EOK on OK, -RT_ERROR on error   */   rt_err_t rt_thread_resume(rt_thread_t thread)   {       register rt_base_t temp;          /* thread check */       RT_ASSERT(thread != RT_NULL);          RT_DEBUG_LOG(RT_DEBUG_THREAD, ("thread resume:  %s\n", thread->name));          if (thread->stat != RT_THREAD_SUSPEND)//只對處於掛起的線程進行還原操作       {           RT_DEBUG_LOG(RT_DEBUG_THREAD, ("thread resume: thread disorder, %d\n",                                          thread->stat));              return -RT_ERROR;       }          /* disable interrupt */       temp = rt_hw_interrupt_disable();//關中斷          /* remove from suspend list */       rt_list_remove(&(thread->tlist));//從掛起隊列中移除          /* remove thread timer */       rt_list_remove(&(thread->thread_timer.list));//因線程即將運行,所以需要移除定時器,無需再定時          /* change timer state */       thread->thread_timer.parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;//將內核對象的標志設置為定時器非激活標志          /* enable interrupt */       rt_hw_interrupt_enable(temp);//開中斷          /* insert to schedule ready list */       rt_schedule_insert_thread(thread);//將線程加入調度器          return RT_EOK;   }     7 線程讓出處理機 當前線程的時間片用完或者該線程自動要求讓出處理器資源時,它不再占有處理機,調度器會選擇下一個最高優先級的線程執行。這時,放棄處理器資源的線程仍然在就緒隊列中,只不過放到就緒隊列末尾去 了. [cpp]  /**   * This function will let current thread yield processor, and scheduler will   * choose a highest thread to run. After yield processor, the current thread   * is still in READY state.   *   * @return RT_EOK   */   rt_err_t rt_thread_yield(void)   {       register rt_base_t level;       struct rt_thread *thread;          /* disable interrupt */       level = rt_hw_interrupt_disable();//關中斷          /* set to current thread */       thread = rt_current_thread;//得到當前線程          /* if the thread stat is READY and on ready queue list */       if (thread->stat == RT_THREAD_READY &&//如果當前線程處於就緒狀態且在就緒隊列           thread->tlist.next != thread->tlist.prev)       {           /* remove thread from thread list */           rt_list_remove(&(thread->tlist));//從就緒隊列中移除當前線程              /* put thread to end of ready queue */           rt_list_insert_before(&(rt_thread_priority_table[thread->current_priority]),//加入到就緒隊列末尾                                 &(thread->tlist));              /* enable interrupt */           rt_hw_interrupt_enable(level);//開中斷              rt_schedule();//重新調度線程              return RT_EOK;       }          /* enable interrupt */       rt_hw_interrupt_enable(level);//開中斷          return RT_EOK;   }     8 線程睡眠 [cpp]   /**   * This function will let current thread sleep for some ticks.   *   * @param tick the sleep ticks   *   * @return RT_EOK   */   rt_err_t rt_thread_sleep(rt_tick_t tick)   {       register rt_base_t temp;       struct rt_thread *thread;          /* disable interrupt */       temp = rt_hw_interrupt_disable();//關中斷       /* set to current thread */       thread = rt_current_thread;//得到當前線程       RT_ASSERT(thread != RT_NULL);          /* suspend thread */       rt_thread_suspend(thread);//掛起當前線程          /* reset the timeout of thread timer and start it */       rt_timer_control(&(thread->thread_timer), RT_TIMER_CTRL_SET_TIME, &tick);//設置定時器       rt_timer_start(&(thread->thread_timer));//啟動定時器          /* enable interrupt */       rt_hw_interrupt_enable(temp);//開中斷          rt_schedule();//啟動調度器          /* clear error number of this thread to RT_EOK */       if (thread->error == -RT_ETIMEOUT)//將當前線程的錯誤碼設置為超時           thread->error = RT_EOK;          return RT_EOK;   }     [cpp]   /**   * This function will let current thread delay for some ticks.   *   * @param tick the delay ticks   *   * @return RT_EOK   */   rt_err_t rt_thread_delay(rt_tick_t tick)   {       return rt_thread_sleep(tick);   }     9 線程控制 [cpp]    * This function will control thread behaviors according to control command.   *   * @param thread the specified thread to be controlled   * @param cmd the control command, which includes   *  RT_THREAD_CTRL_CHANGE_PRIORITY for changing priority level of thread;   *  RT_THREAD_CTRL_STARTUP for starting a thread;   *  RT_THREAD_CTRL_CLOSE for delete a thread.   * @param arg the argument of control command   *   * @return RT_EOK   */   rt_err_t rt_thread_control(rt_thread_t thread, rt_uint8_t cmd, void *arg)   {       register rt_base_t temp;          /* thread check */       RT_ASSERT(thread != RT_NULL);          switch (cmd)       {       case RT_THREAD_CTRL_CHANGE_PRIORITY://修改優先級           /* disable interrupt */           temp = rt_hw_interrupt_disable();//關中斷              /* for ready thread, change queue */           if (thread->stat == RT_THREAD_READY)//如果線程處於就緒狀態           {               /* remove thread from schedule queue first */               rt_schedule_remove_thread(thread);//移除                  /* change thread priority */               thread->current_priority = *(rt_uint8_t *)arg;//設置優先級                  /* recalculate priority attribute */   #if RT_THREAD_PRIORITY_MAX > 32               thread->number      = thread->current_priority >> 3;            /* 5bit */               thread->number_mask = 1 << thread->number;               thread->high_mask   = 1 << (thread->current_priority & 0x07);   /* 3bit */   #else               thread->number_mask = 1 << thread->current_priority;   #endif                  /* insert thread to schedule queue again */               rt_schedule_insert_thread(thread);//加入調度器           }           else           {               thread->current_priority = *(rt_uint8_t *)arg;                  /* recalculate priority attribute */   #if RT_THREAD_PRIORITY_MAX > 32               thread->number      = thread->current_priority >> 3;            /* 5bit */               thread->number_mask = 1 << thread->number;               thread->high_mask   = 1 << (thread->current_priority & 0x07);   /* 3bit */   #else               thread->number_mask = 1 << thread->current_priority;   #endif           }              /* enable interrupt */           rt_hw_interrupt_enable(temp);           break;          case RT_THREAD_CTRL_STARTUP://啟動           return rt_thread_startup(thread);      #ifdef RT_USING_HEAP       case RT_THREAD_CTRL_CLOSE://關閉線程           return rt_thread_delete(thread);   #endif          default:           break;       }          return RT_EOK;   }     10 查找線程 [cpp]  /**   * This function will find the specified thread.   *   * @param name the name of thread finding   *   * @return the found thread   *   * @note please don't invoke this function in interrupt status.   */   rt_thread_t rt_thread_find(char *name)   {       struct rt_object_information *information;       struct rt_object *object;       struct rt_list_node *node;          extern struct rt_object_information rt_object_container[];          /* enter critical */       if (rt_thread_self() != RT_NULL)           rt_enter_critical();//進入臨界區          /* try to find device object */       information = &rt_object_container[RT_Object_Class_Thread];//從內核對象容器中獲取內核對象鏈表       for (node  = information->object_list.next;            node != &(information->object_list);            node  = node->next)       {           object = rt_list_entry(node, struct rt_object, list);//得到內核對象           if (rt_strncmp(object->name, name, RT_NAME_MAX) == 0)//比較名字           {  www.2cto.com             /* leave critical */               if (rt_thread_self() != RT_NULL)                   rt_exit_critical();//退出臨界區                  return (rt_thread_t)object;//返回內核對象           }       }          /* leave critical */       if (rt_thread_self() != RT_NULL)           rt_exit_critical();//退出臨界區          /* not found */       return RT_NULL;//返回未找到   }    

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved