线程状态机
同一进程或内核中的多个线程之间可以并发执行。但由于线程之间的相互制约,致使线程在运行中呈现出间断性。
线程具有阻塞、就绪和运行三种基本状态。这三种状态的含义如下:
- 初始 :初始态是 SylixOS 中通过初始化线程接口创建线程时的一种状态,该状态下的线程并没有加入到系统就绪表,通常需要通过“启动”的方式将目标线程加入就绪表,从而进入就绪态。
- 阻塞 :线程缺少使其运行的条件或资源,必须等条件满足后方可进入就绪态。
- 就绪 :线程已经拥有使其运行的一切资源,等待操作系统调度。
- 运行 :线程已被操作系统调度(操作系统将一个 CPU 分配给线程用于执行线程代码)。
SylixOS 中被创建出来的线程总是处于这三种状态中的任意一种,其中阻塞态又因阻塞原因不同分为:等待信号量、等待消息、睡眠等。线程之间的状态切换如下图所示。
在上图中,初始态只是线程被创建前的一个状态,我们看其他三种状态的切换关系:
- 就绪→运行:就绪态的线程开始被系统调度,获得了 CPU 的使用权。
- 运行→就绪:运行态线程被其他线程抢占或主动放弃了 CPU 的使用权。
- 就绪→阻塞:其他线程主动将其挂起(SylixOS 不推荐使用)。
- 阻塞→就绪:等待的资源变得可用。
- 运行→阻塞:等待信号量、接收消息、睡眠等使其进入阻塞。
这里需要说明的是 SylixOS 不推荐使用线程 suspend 函数来使其他线程挂起(阻塞的一种),这样会破坏程序的结构化设计,使应用程序的设计变得复杂与不可预测,容易出现设计错误。
分析完这些状态转换关系后,我们来看一下 SylixOS 中引起这些状态变化的应用程序接口函数:
函数名 | 状态变化 |
---|---|
Lw_Thread_Create | 创建一个线程,且线程会进入就绪态 |
Lw_Thread_Init | 初始化一个线程,线程进入初始状态 |
Lw_Thread_Start | 使一个处于初始状态的线程进入就绪态 |
Lw_Thread_Suspend | 使线程挂起进入阻塞态(不推荐使用) |
Lw_Thread_Resume | 使线程从阻塞态进入就绪态(不推荐使用) |
Lw_Thread_ForceResume | 强制使线程进入就绪态(不推荐使用) |
Lw_Thread_Yield | 使线程主动放弃 CPU 进入就绪态 |
Lw_Thread_Wakeup | 线程从睡眠模式唤醒进入就绪态 |
Lw_Semaphore_Wait | 使线程阻塞 |
Lw_Semaphore_Post | 使线程从阻塞态恢复到就绪态 |
Lw_SemaphoreC_Wait | 使线程阻塞 |
Lw_SemaphoreC_Post | 使线程从阻塞态恢复到就绪态 |
Lw_SemaphoreB_Wait | 使线程阻塞 |
Lw_SemaphoreB_Post | 使线程从阻塞态恢复到就绪态 |
Lw_SemaphoreM_Wait | 使线程阻塞 |
Lw_SemaphoreM_Post | 使线程从阻塞态恢复到就绪态 |
Lw_MsgQueue_Receive | 使线程阻塞 |
Lw_MsgQueue_Send | 使线程从阻塞态恢复到就绪态 |
Lw_Time_Sleep | 线程睡眠进入阻塞态 |
Lw_Time_SSleep | 线程睡眠进入阻塞态 |
Lw_Time_MSleep | 线程睡眠进入阻塞态 |