任务的调度和切换

一、任务的状态

任务的5种状态:休眠态、就绪态、运行态、挂起态(等待某一事件发生)和被中断态。

1、休眠态

任务驻留在内存中,但并不被多任务内核所调度。

2、就绪态

任务已经准备好,可以运行,但由于该任务的优先级比正在运行的任务的优先级低,暂时不能运行。

3、运行态

任务掌握了CPU的使用权,正在运行中。

4、挂起态

也叫等待事件态,指任务在等待某一事件的发生。例如:等待某外设的I/O操作,等待某共享资源由暂不能使用变成能使用状态,等待定时脉冲的到来,以结束目前的等待。

5、被中断态

发生中断时,CPU提供相应的中断服务,原来正在运行的任务暂不能运行。

二、任务的调度

任务级的调度是由函数OS_Sched()完成的。uC/OS-II任务调度的执行时间是常数,与应用程序建立了多少个任务没有关系。

 1 void  OS_Sched (void)
 2 {
 3 #if OS_CRITICAL_METHOD == 3                            /* Allocate storage for CPU status register     */
 4     OS_CPU_SR  cpu_sr;
 5 #endif
 6     INT8U      y;
 7
 8
 9     OS_ENTER_CRITICAL();
10     if ((OSIntNesting == 0) && (OSLockNesting == 0)) { /* Sched. only if all ISRs done & not locked    */
11         y             = OSUnMapTbl[OSRdyGrp];          /* Get pointer to HPT ready to run              */
12         OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]);
13         if (OSPrioHighRdy != OSPrioCur) {              /* No Ctx Sw if current task is highest rdy     */
14             OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
15             OSCtxSwCtr++;                              /* Increment context switch counter             */
16             OS_TASK_SW();                              /* Perform a context switch                     */
17         }
18     }
19     OS_EXIT_CRITICAL();
20 }

(1)OS_Sched()检验这个优先级最高的任务是否是当前正在运行的任务,以避免不必要的任务调度。

(2)统计计数器OSCtxSwCtr的使用目的是让用户知道每秒做了多少次任务切换。

(3)调用OS_TASK_SW()宏,完成实际上的任务切换。

三、任务级的任务切换

任务切换代码须恢复该任务在CPU使用权被剥夺时保存下来的全部寄存器的值,以便让这个任务能继续运行。任务切换由2步完成:将被挂起任务的处理器寄存器推入堆栈,然后将较高优先级任务的寄存器值从栈中恢复到寄存器。OS_TASK_SW()挂起了正在执行的任务,而让CPU执行更重要的任务。

任务切换过程增加了应用程序的额外负荷,CPU的内部寄存器越多,额外负荷越重。任务切换所需时间取决于CPU有多少寄存器要入栈。

OS_TASK_SW()是宏调用,通常含有微处理器的软中断指令,因为uC/OS-II假定任务切换是靠软中断完成的。OS_TASK_SW()通常是汇编语言写的,因为C编译器不能从C语言中直接处理CPU寄存器。

四、给调度器上锁和开锁

(1)给调度器上锁函数OSSchedLock()用于禁止任务调度,直到任务完成之后,调用给调度器开锁函数OSSchedUnlock()为止。

(2)调用OSSchedLock()的任务,保持对CPU的使用权,尽管有个优先级更高的任务进入了就绪态。

(3) OSSchedLock()和OSSchedUnlock()必须成对使用。变量OSLockNesting跟踪OSSchedLock()函数被调用的次数。当OSLockNesting=0时,调度重新得到允许。

(4)如果多任务已经启动了(已经调用过OSStart()),则给调度器上锁和开锁才有意义。

(5)调用OSSchedLock()之后,应用程序不得调用可能会使当前任务挂起的系统功能函数,直到OSLockNesting=0为止。

时间: 2024-10-16 15:19:52

任务的调度和切换的相关文章

任务的调度与切换(uC/OS-II)

一.任务的状态 任务的5种状态:休眠态.就绪态.运行态.挂起态(等待某一事件发生)和被中断态. 1.休眠态 任务驻留在内存中,但并不被多任务内核所调度. 2.就绪态 任务已经准备好,可以运行,但由于该任务的优先级比正在运行的任务的优先级低,暂时不能运行. 3.运行态 任务掌握了CPU的使用权,正在运行中. 4.挂起态 也叫等待事件态,指任务在等待某一事件的发生.例如:等待某外设的I/O操作,等待某共享资源由暂不能使用变成能使用状态,等待定时脉冲的到来,以结束目前的等待. 5.被中断态 发生中断时

高级操作系统实验2-进程调度与切换分析(1)

实验目的:掌握linux进程调度的工作原理和实现方式,提高内核调度技术. 实验内容:编一个程序在3个进程中分别循环输出字母A/B/C,每输出一个字母就主动放弃CPU:然后通过对内核的调度,画出3个进程运行的详细时序图和概要时序图,时序图的时间范围涵盖上述字母至少2个(可以相同),要求在详细的时序图中标注下列控制点信息: 调度的开始及原因和结束.进程切换的开始: 中断处理的开始和结束.软中断处理的开始和结束: 系统调用的开始及系统调用号和结束: 缺页等异常的开始和结束 增加和删除CFS运行队列中的

处理机调度:调度的概念、时机、切换、过程以及调度方式和基本准则

调度的概念 在多道程序系统中,进程的数量往往多于处理机的个数,进程争用处理机的情况就在所难免.处理机调度是对处理机进行分配,就是从就绪队列中,按照一定的算法(公平.髙效)选择一个进程并将处理机分配给它运行,以实现进程并发地执行. 处理机调度是多道程序操作系统的基础,它是操作系统设计的核心问题. 调度的时机.切换与过程 进程调度和切换程序是操作系统内核程序.当请求调度的事件发生后,才可能会运行进程调度程序,当调度了新的就绪进程后,才会去进行进程间的切换.理论上这三件事情应该顺序执行,但在实际设计中

Chromium硬件加速渲染的OpenGL上下文调度过程分析

Chromium的每一个WebGL端.Render端和Browser端实例在GPU进程中都有一个OpenGL上下文.这些OpenGL上下文运行在相同线程中,因此同一时刻只有一个OpenGL上下文处于运行状态.这就引发出一个OpenGL上下文调度问题.此外,事情有轻急缓重,OpenGL上下文也有优先级高低之分,优先级高的要保证它的运行时间.本文接下来就分析GPU进程调度运行OpenGL上下文的过程. 老罗的新浪微博:http://weibo.com/shengyangluo,欢迎关注! 在前面Ch

Linux内核分析:实验八--Linux进程调度与切换

刘畅 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 概述 这篇文章主要分析Linux中,进程调度和上下文切换的过程,会涉及到进度调度的时机和进程的切换执行过程,并通过GDB跟踪Linux的schedule()函数来比较深入的理解一下这个过程. 进程调度策略与调度时机 调度策略 操作系统中包含有很多进程调度的算法,内核会依据进程的属性来选择不同的调度策略.进程可以比较粗略的分为:IO密集

【操作系统】知识点总结之进程管理与调度

1.中央处理器 1.1 CPU:处理器由运算器.控制器.一系列的寄存器以及高速缓存构成 运算器实现指令中的算术和逻辑运算,是计算机计算的核心 控制器负责控制程序运行的流程,包括取指令.维护CPU状态.CPU与内存的交互等等 寄存器是指令在CPU内部作处理的过程中暂存数据.地址以及指令信息的存储设备.在计算机的存储系统中它具有最快的访问速度.包括用户可见寄存器,控制寄存器. 用户可见寄存器 高级语言编译器通过算法分配并使用之,以减少程序访问主存次数 包括通用寄存器.数据寄存器.地址寄存器 数据寄存

Linux下的进程类别(内核线程、轻量级进程和用户进程)以及其创建方式--Linux进程的管理与调度(四)

本文声明 日期 内核版本 架构 作者 GitHub CSDN 2016-05-12 Linux-4.5 X86 & arm gatieme LinuxDeviceDrivers Linux进程管理与调度-之-进程的创建 本文中出现的,内核线程,轻量级进程,用户进程,用户线程等概念,如果不太熟悉, 可以参见 内核线程.轻量级进程.用户线程三种线程概念解惑(线程≠轻量级进程) Linux进程类别 虽然我们在区分Linux进程类别, 但是我还是想说Linux下只有一种类型的进程,那就是task_str

go的调度 与 go 的GC

go的调度 与 go 的GC 调度 首先golang的goroutine占用的资源非常小,默认size是2k,goroutine调度的切换也不用到内核层去完成,代价很低,所以go可以创建成千上万个goroutine.对于操作系统而言,go程序是一个用户层程序,对goroutine是不可见的,所以goroutine的调度要靠go自己来实现,也就是go runtime. 经过发展后,现在的Go调度器模型是GPM模型,算法是work stealing算法. G就是goroutine,M指的是CPU,P

Linux内核源码分析--内核启动之(5)Image内核启动(rest_init函数)(Linux-3.0 ARMv7)【转】

原文地址:Linux内核源码分析--内核启动之(5)Image内核启动(rest_init函数)(Linux-3.0 ARMv7) 作者:tekkamanninja 转自:http://blog.chinaunix.net/uid-25909619-id-4938395.html 前面粗略分析start_kernel函数,此函数中基本上是对内存管理和各子系统的数据结构初始化.在内核初始化函数start_kernel执行到最后,就是调用rest_init函数,这个函数的主要使命就是创建并启动内核线