Chinaunix首页 | 论坛 | 博客
  • 博客访问: 26075
  • 博文数量: 12
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 82
  • 用 户 组: 普通用户
  • 注册时间: 2015-11-30 14:36
文章分类

全部博文(12)

文章存档

2016年(7)

2015年(5)

我的朋友

分类: 嵌入式

2016-09-12 17:08:44


进程状态间的切换图。PROCESS_STATE_NONE在该状态下进程在进程链表中,但是不能获取CPU使用权。PROCESS_STATE_RUNNING为进程可以运行,但还未获得CPU使用权,PROCESS_STATE_CALLED为进程正在运行。

进程状态切换

PROCESS_STATE_NONE- > PROCESS_STATE_RUNNING状态切换:该状态切换调用process_start(),该函数有两个作用:将进程挂载到进程链表中,并切换状态,其二将发送同步事件,让进程第一次运行。

点击(此处)折叠或打开

  1. void process_start(struct process *p, process_data_t data)
  2. {
  3.   struct process *q;

  4.   /**判断新加入进程是否在进程链表中
  5.    * 
  6.    */
  7.   for(q = process_list; q != p && q != NULL; q = q->next);
  8.   if(q == p) {
  9.     return;
  10.   }

  11.   /* 插入进程链表,并切换状态*/
  12.   p->next = process_list;
  13.   process_list = p;
  14.   p->state = PROCESS_STATE_RUNNING;
  15.   PT_INIT(&p->pt);

  16.   PRINTF("process: starting '%s
  17.   process_post_synch(p, PROCESS_EVENT_INIT, data); /**<调用同步事件,使进程运行一次 */
  18. }


PROCESS_STATE_RUNNING ->PROCESS_STATE_CALLED状态切换:该状态调用call_process()。上述发送同步事件让进程执行一次。
PROCESS_STATE_CALLED -> PROCESS_STATE_RUNNING 状态切换:在调用call_process()中若进程没有自己终端自己或者没有其他任务终结自己,切换到running状态,等待下一次运行。

点击(此处)折叠或打开

  1. void process_post_synch(struct process *p, process_event_t ev, process_data_t data)
  2. {
  3.   /**process_current可以被用来判断删除的是否是当前的任务
  4.    */
  5.   struct process *caller = process_current; /**<指向当前运行进程 */

  6.   call_process(p, ev, data);
  7.   process_current = caller;
  8. }


点击(此处)折叠或打开

  1. static void call_process(struct process *p, process_event_t ev, process_data_t data)
  2. {
  3.   int ret;
  4.   
  5.   if((p->state & PROCESS_STATE_RUNNING) &&    /**< 函数是即将运行态,运行进程*/
  6.      p->thread != NULL) {
  7.     process_current = p;
  8.     p->state = PROCESS_STATE_CALLED;         /**< 更改进程为正在运行态 */
  9.     ret = p->thread(&p->pt, ev, data);       /**< 运行线程 */
  10.     if(ret == PT_EXITED ||
  11.        ret == PT_ENDED ||
  12.        ev == PROCESS_EVENT_EXIT) {
  13.       /**根据进程运行结果(是否结束自己)和事件类型判断是否需要退出。一个进程可以主动结束
  14.        * 或者A进程调用事件通知B进程结束结束
  15.        */
  16.       exit_process(p, p);                  
  17.     } else {
  18.       p->state = PROCESS_STATE_RUNNING; /**< 直接切换到running状态,等待下一次运行 */
  19.     }
  20.   }
  21. }
PROCESS_STATE_CALLED -> PROCESS_STATE_NONE:此次切换表示进程自己终结自己;
PROCESS_STATE_RUNNING -> PROCESS_STATE_NONE:其他任务终结自己;
无论是自己结束自己,还是其他进程结束自己,均需要调用exit_process()

点击(此处)折叠或打开

  1. static void exit_process(struct process *p, struct process *fromprocess)
  2. {
  3.   register struct process *q;
  4.   struct process *old_current = process_current;

  5.   for(q = process_list; q != p && q != NULL; q = q->next); /**<确保被删除的进程在进程链表中 */
  6.   if(q == NULL) {
  7.     return;
  8.   }
  9.   /**进程在运行状态,包含两种PROCESS_STATE_RUNNING(被其他线程终结) PROCESS_STATE_CALLED(被自己终结)
  10.    * 如果是在运行状态终结任务,那么有可能被终结的任务绑定一些事件,那么此处应该把被终结任务绑定的事件移除。
  11.    * 例如,print_hello_process进程被删除,则需要通知etimer进程把与该任务相关的定时器移除。因为该事件绑定
  12.    * 了进程的地址
  13.    */
  14.   if(process_is_running(p)) {

  15.     p->state = PROCESS_STATE_NONE;   /**<切换状态 */

  16.     for(q = process_list; q != NULL; q = q->next) {
  17.       if(p != q) {
  18.         call_process(q, PROCESS_EVENT_EXITED, (process_data_t)p);/**< 通知其他线程,某个线程已经退出,把与我有关的事件删除*/
  19.       }
  20.     }
  21.     /**如果是被其他进程删除的,通知被删除的进程,其被删除
  22.      */
  23.     if(p->thread != NULL && p != fromprocess) {
  24.       process_current = p;
  25.       p->thread(&p->pt, PROCESS_EVENT_EXIT, NULL);
  26.     }
  27.   }
  28.   /**此处是PROCESS_STATE_NONE状态说明与被删除任务相关的事件已经被删除,可以从线程链表中移除删除的任务了 
  29.    *
  30.    */
  31.   if(p == process_list) {
  32.     process_list = process_list->next;
  33.   } else {
  34.     for(q = process_list; q != NULL; q = q->next) {
  35.       if(q->next == p) {
  36.     q->next = p->next;
  37.     break;
  38.       }
  39.     }
  40.   }

  41.   process_current = old_current;
  42. }







阅读(411) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~