本文分析了Contiki OS进程3种状态PROCESS_STATE_NONEPROCESS_STATE_RUNNINGPROCESS_STATE_CALLED,并给出进程状态转换图。

1. 进程状态概述

Contiki是事件驱动内核,并基于protothread机制提供类线程编程风格(a thread-like programming style),在博文《protothread状态》已介绍了protothread状态,但进程的状态与protothread不尽相同,只有3种状态,如下:

#define PROCESS_STATE_NONE    0
#define PROCESS_STATE_RUNNING 1
#define PROCESS_STATE_CALLED  2

PROCESS_STATE_NONE是指进程不处于运行状态,而PROCESS_STATE_RUNNINGPROCESS_STATE_CALLED都属于运行状态,区别在于:后者确确实实在执行,即获得执行权(被调用了);前者表示就绪状态。进程状态转换图如下,详情见下述分析(visio源文件:进程状态转换图.vsd):

process status

2. PROCESS STATE

2.1 PROCESS_STATE_NONE

进程退出(但此时还没从进程链表删除),先将进程状态设为PROCESS_STATE_NONE,而后再从进程链表删除,详情见博文《启动一个进程process_start》第四部分exit_process函数。部分源码如下:

if (process_is_running(p))
{
  p->state = PROCESS_STATE_NONE;

process_is_running函数用于判断进程是否处于运行状态(包括PROCESS_STATE_RUNNINGPROCESS_STATE_CALLED),看源码就很清楚了:

int process_is_running(struct process *p)
{
  return p->state != PROCESS_STATE_NONE;
}

除此之外,声明一个进程时,进程状态默认也为PROCESS_STATE_NONE。在博文《实例hello_world剖析》讨论中,宏PROCESS用于声明一进程函数主体和定义一进程,宏展开如下:

#define PROCESS(name, strname) PROCESS_THREAD(name, ev, data); \
struct process name = { NULL, strname, process_thread_##name }

定义进程name,只初始化前3个变量,其余的缺省为0,当然也包括进程状态,而PROCESS_STATE_NONE又被define为0。关于进程结构体可参见博文《主要数据结构之进程》。

2.2 PROCESS_STATE_RUNNING

启动一个进程(由函数process_start完成),将进程加入进程链表process_list,而后把进程状态设为PROCESS_STATE_RUNNINGcall_process函数(真正执行进程主体thread)会根据进程状态决定是否执行进程主体thread,详情见博文《启动一个进程process_start》。即进程获得执行权的时候,先把进程状态设为PROCESS_STATE_RUNNING,而后再正在执行进程主体thread

2.3 PROCESS_STATE_CALLED

call_process函数中,在执行进程主体thread前,先把进程设为PROCESS_STATE_CALLED,部分源码如下:

if ((p->state &PROCESS_STATE_RUNNING) && p->thread != NULL)
{
  process_current = p;
  p->state = PROCESS_STATE_CALLED;

  ret = p->thread(&p->pt, ev, data);
  if (ret == PT_EXITED || ret == PT_ENDED || ev == PROCESS_EVENT_EXIT)
  {
    exit_process(p, p);
  }
  else
  {
    p->state = PROCESS_STATE_RUNNING;
  }
}

源代码很少地方用到PROCESS_STATE_CALLED,表示进程被调用,正在执行。佐证如下:

//call_process函数的部分代码
#if DEBUG
  if (p->state == PROCESS_STATE_CALLED)
  {
    printf("process: process '%s' called again with event %d\n",
      PROCESS_NAME_STRING(p), ev);
  }
#endif
本文系Spark & Shine原创,转载需注明出处本文最近一次修改时间 2022-03-22 22:35

results matching ""

    No results matching ""