操作系统课程设计——处理机管理
操作系统4、处理机
06 处理机调度的实现方式
非抢占式调度的实现方式
进程自己让出处理器
当一个进程在计算过程中,需要执行I/O操作时,它必须先完成该I/O操作后才 能继续执行。在此期间,该进程会主动放弃处理器,并放入就绪队列中等待。
进程等待I/O操作完成
当一个进程正在等待I/O操作完成时,它必须一直等待,直到所需的I/O操作完 成。在此期间,处理器可能被分配给其他进程。
线程之间通信和同步更加灵活 ,可以更好地利用多核处理器 资源。
线程具有轻量级、高并发性、 独立性等特点。
线程状态
01
就绪状态
线程已经准备好运行,等待获取 CPU资源。
阻塞状态
02
03
终止状态
线程因等待某个条件成立而无法 继续执行,需要等待一段时间后 才能重新进入就绪状态。
线程执行完毕或因异常而结束执 行。
线程同步与互斥
互斥
同一时刻只允许一个线程访问共 享资源,以避免数据不一致和冲 突。
同步
协调多个线程之间的执行顺序和 时间,以确保它们能够正确地协 作完成任务。
线程实现方式
用户级线程(ULT)
在用户空间实现线程,操作系统不直接管理 线程,而是由应用程序自己管理。
内核级线程(KLT)
在内核空间实现线程,操作系统直接管理和 调度线程。
优先级调度算法
总结词
根据作业优先级进行调度,优先级高的作业先执行。
详细描述
优先级调度算法是一种非抢占式的算法,它根据作业的 优先级进行调度。系统会为每个作业分配一个优先级, 优先级高的作业将先于优先级低的作业执行。当一个作 业到达时,系统会检查其所需资源是否可用,如果可用 ,则将其放入等待队列中,等待处理机空闲时执行。这 种算法的优点是能够快速地处理紧急任务,但可能导致 一些低优先级的作业等待时间过长。
操作系统 处理机管理
实验一、处理机管理一、实验内容处理机管理是操作系统中非常重要的部分。
为深入理解进程管理部分功能,设计几个调度算法,模拟实现处理机的调度。
二、实验目的在多道程序或多道任务系统中,系统同时处于就绪态的进程有若干个。
也就是说能运行的进程远远大于处理机个数。
为了使系统中的各进程能有条不紊地运行,必须选择某种调度策略,以选择一进程占用处理机。
要求学生设计一个模拟单处理机调度算法,以巩固和加深处理机调度的概念。
三、实验题目1、设计一个按时间片轮转法调度的算法(代码见四,需调试并加注释)在做2~5之前制作一菜单,以调用各算法2、在1基础上增加一个按先来先服务调度的算法3、在2基础上增加一个按优先级调度的算法4、*在3基础上增加一个短作业优先的算法5、*在4基础上增加一个高响应比的算法打“*”题目属较难题目。
四、实验程序1、时间片轮转法调度的算法C实现:运行结果:Java实现关键代码:当前处于处理机的进程的执行过程时间片轮转算法实现:输入:输出:时间片为 1 时:(运行过程)(计算周转时间和带权周转时间)时间片为 4 时:2、先来先服务算法关键代码:输入情况:(为了避免重复调试输入数据,于是从文本文件中读取数据)输出结果:3、优先级调度算法关键代码:输入情况:输出结果:3、短作业优先(注意此短作业优先是非抢占式的!)关键代码:短作业优先算法和先来先服务算法思想类似,短作业主要是判断当前到达的进程的服务时间是否是就绪队列中最小的,如果是,则在当前进程执行完毕后,此短作业处于就绪队列的头部输入:输出结果:5、高响应比优先级调度算法设置了8个进程任务,由系统自动产生。
操作系统处理机管理
操作系统处理机管理在计算机系统中,操作系统起着至关重要的作用,就像是一个大管家,精心管理着各种资源,确保系统的高效运行。
其中,处理机管理是操作系统的核心任务之一。
处理机,简单来说就是我们常说的 CPU(中央处理器),它是计算机的“大脑”,负责执行各种指令和计算任务。
而操作系统的处理机管理,就是要合理地分配和调度处理机资源,让各个程序和任务能够公平、高效地使用处理机,从而提高整个系统的性能和效率。
为什么处理机管理如此重要呢?想象一下,如果多个程序同时需要使用处理机,但没有一个有效的管理机制,就会出现混乱。
有些程序可能长时间占用处理机,导致其他程序无法及时得到执行,系统的响应速度就会变得很慢,用户体验也会大打折扣。
所以,处理机管理的好坏直接影响着计算机系统的性能和用户的满意度。
处理机管理主要包括进程管理和线程管理两个方面。
进程,是指一个正在运行的程序的实例。
每个进程都有自己独立的地址空间、资源和执行状态。
操作系统通过进程管理来控制进程的创建、终止、切换和同步等操作。
当我们打开一个应用程序时,操作系统就会为它创建一个进程。
在进程运行过程中,可能会因为等待输入输出、时间片用完等原因而暂时停止执行,这时操作系统就会把处理机切换到其他就绪的进程上,以充分利用处理机资源。
进程的切换是一个复杂的过程,需要保存当前进程的运行状态,包括程序计数器、寄存器的值等,然后恢复下一个要执行的进程的状态。
进程同步则是为了协调多个进程之间的执行顺序,避免出现错误。
比如,两个进程同时对一个共享资源进行读写操作,如果没有同步机制,就可能会导致数据不一致的问题。
线程是进程中的一个执行单元,它共享进程的地址空间和资源,但有自己的执行栈和寄存器。
线程管理比进程管理更加轻量级,创建和切换线程的开销要比进程小得多,因此在一些需要并发执行多个任务的场景中,使用线程可以提高系统的性能。
在处理机管理中,调度算法是关键。
常见的调度算法有先来先服务(FCFS)、短作业优先(SJF)、时间片轮转(RR)、优先级调度等。
操作系统---处理机管理
进程调度程序的功能
记录系统中所有进程的有关情况 确定分配处理机的算法 完成处理机的分配 完成处理机的回收
引起进程调度的事件
有四种情况都会发生CPU调度: 当一个进程从运行态切换成阻塞态时; 当一个进程从运行态切换成就绪态时; 当一个进程从阻塞态切换成就绪态时; 当一个进程中止时。
优先数设立原则
根据进程的类型:用户进程,系统进程 根据进程执行任务的重要性 根据进程程序的性质:cpu繁忙,I/O繁忙 根据对资源的需求 根据用户的请求
优先数类型
静态优先数:进程生命周期内不会改变 动态优先数:进程生命周期内随时修改
UNIX动态优先数计算公式
Switch:采用动态优先数法
OS:释放资源,返回结果信息或错误信息、返回父程序。
CPU管理功能的工作内容与任务
3.提高对CPU的利用率,实现并发技术(实现多个程 序对CPU的并发共享) OS:建立进程,进程切换,调度,进程通信 4.向用户程序提供与CPU使用相关的用户接口 操作系统提供的系统调用中与CPU使用相关的有:
在一个程序中启动另一程序 程序结束 关于信号操作的一组系统调用等等
所谓“进程”,是指一个程序在给定数据集合上的一次 执行过程,是系统进行资源分配和运行调度的独立单位。 进程的分类
系统进程 用户进程
2.1.3 进程的特征
1. 进程与程序的关系
进程是程序的一次执行过程,程序是进程赖以存在的基础。 2. 进程与程序的区别 ―进程”是一个动态的概念 不同进程可以执行同一个程序 每个进程都有自己的生命期 进程之间具有并发性 进程间会相互制约
就绪队列
级1 到达 (先来先服务) 时间片到 级2 (先来先服务)
OS处理机管理PPT教案
(3) 独立性 这是指进程实体是一个能够独立运行的基本单位,同时也 是系统中独立获得资源和独立调度的基本单位。
(4) 异步性 这是指进程按各自独立的不可预知速度向前推进,或者 说,进程按异步方式运行。这是由于进程间共享资源和协 同合作时带来了相互间制约的关系,造成进程执行的间断 性。
进程调度程序的职能: (1)记录系统中所有进程的有关情
况。 (2)确定分配处理机的原则。 (3)分配处理机给进程。 (4)从进程收回处理机。
返回本节目录
3.4.2 进程调度所用的主要数据结构
PCB的组织形式 方法有三: (1)线性表:简单,但进程多时查找速度慢!
(2)链接表:相同状态的进程PCB按优先数 排成一个或多个队列,如就绪队列,不同事件 的阻塞队列
另外,不论是系统程序还是用户程序,由 于它们并行地在着系统中运行,并且有着各 种复杂的制约关系,所以它们在系统内部所 处的状态不断发生变化,时而在CPU上执行, 时而因某种原因被暂停执行。由于在这样一 个多道程序系统所带来的复杂环境中,使程 序具有了并行、制约和动态的特性,使得原
2)程序和机器执行程序的活动是两个概念。 程序是指令的有序集合,是静态的概念, 而机器执行程序的活动是指指令序列在处 理机上的执行过程,或处理机按照程序执 行指令序列的过程。而且由于竞争资源等 其他因素,程序执行时走走停停,具有 “执行—暂停—执行”的活动规律。所以 就无法用“程序”这个静态的概念来描述 程序运行的过程,为此,引入了一个新的 一个动态的概念——“进程”
的PCB
内容回顾
进程的基本状态 进程状态之间的转换
处理机调度课程设计模板 操作系统
八、指导教师评语
签名:
年月日
课程设计成绩
附:1、课程设计的填写请按格式要求做;
2、文字内容宋体、五号、1.5倍行距;
3、程序代码字体Times New Roman,五号、1.5倍行距;
《操作系统》课程设计
处理机调度问题实践
系院:计算机科学系
学生姓名:xxxxxxx
学号:xxxxxxxxxxxx
专业:xxxxxxxxxxxx
年级:xxxxxxx
完成日期:xxxx年xx月
指导教师:刘栓
一、课程设计的性质与任务
1、加深对多道程序并发概念的理解,通过编程模拟处理机调度的流程。
2、培养学生能够独立进行知识综合,独立开发较大程序的能力。
2、根据单处理机,多任务的问题特性做好软件实现的需求分析。
3、可根据问题的实际需要,可选择进程数量。
4、当系统运行时,能直观地、动态地反映当前处理机状态及各进程执行的状况。
5、要求在系统安全状态的前提下,兼顾各个进程的公平。
三、课程设计的时间安排
课程设计总时间:8学时
四、课程设计的实验环境
硬件环境:CPU Intel(R) Core™2 Duo E4600 2.40GHz,内存DDR2 1.00GB,
3、培养提高学生软件开发能力和软件的调试技术。
4、培养学生开发大型程序的方法和相互合作的ቤተ መጻሕፍቲ ባይዱ神。
5、培养学生的创新意识。
6、培养学生的算法设计和算法分析能力。
7、培养学生对问题进行文字论述和文字表达的能力。
二、课程设计的内容及其要求
1、可利用先来先服务、短作业优先、响应比高者优先、多级反馈队列模型、时间片轮转法等,来实现处理机的调度。
操作系统—处理机管理
0.4
0.2
FCFS
• 调入顺序 1、2、3、4、5
5 4 3 2 1 0.5 0 t5=0.7+0.5+0.4+0.4+0.2-0.6=1.6
t4=0.7+0.5+0.4+0.4-0.5=1.5 t3=0.7+0.5+0.4-0.4=1.2 t2=0.7+0.5-0.2=1
t1=0.7
0.2 0.4 0.6 0.7
1. 程序执行是断断续续的; 2. 程序与其它程序共享资源; 3. 程序的执行过程不可再现。
1、程序执行的不连续性
单道程序执行: 等待CPU
3 2 1 输入输出 执行
多道程序执行(以分时系统为例):
3 2 1
2、与其它程序共享资源
• 从上例可以看出,多道程序在执行时, 一个程序要与其它程序共享CPU资源,实 际上,在多道程序运行时,包括内存、 外部设备在内的各种资源都需要共享 (竞争),在后面的内存管理和设备管 理章节中会有更详细的阐述。
作业三
作业二
作业一
0
2
4
6
8
10 12 14
16 18
20 22
24 26 28 30
32 34 36 38
40
例题2平均周转时间
T1=30秒 T2=28.5+6=34.5秒(从1.5—30秒等待作业A完成) T3=33.5+2=35.5秒(从2.5—36秒等待作业A和B完成) 则:T=(T1+T2+T3)/3=(30+34.5+35.5)/3=33.33(秒)
T=(0.7+0.3+0.9+1.2+2)/5=1.02
《操作系统》3处理机管理
进程的定义与状态
总结词
进程是程序的一次执行,具有动态性、并发性和独立 性。进程的状态包括新建、就绪、运行和阻塞。
详细描述
进程是程序在某个数据集合上的一次执行过程,是系 统进行资源分配和调度的基本单位。进程具有动态性 ,即进程的创建、撤销和切换是动态发生的。进程还 具有并发性和独立性,即多个进程可以同时执行,且 每个进程拥有独立的地址空间和系统资源。进程的状 态根据其执行情况和资源需求的不同而有所变化,包 括新建、就绪、运行和阻塞等状态。
个进程可以相互交换数据、协调工作,共同完成复杂的任务。
进程的优先级与调度
总结词
操作系统根据一定的调度算法为就绪状态的进程分配 处理机,以实现资源的合理利用和提高系统的吞吐量 。
详细描述
在多道程序环境下,操作系统需要根据一定的调度算 法为就绪状态的进程分配处理机,以实现资源的合理 利用和提高系统的吞吐量。常见的调度算法包括先来 先服务、最短作业优先、优先级调度等。这些算法各 有优缺点,适用于不同的场景和需求。在选择调度算 法时,需要考虑系统的负载情况、资源的利用率、响 应时间等因素,以确保系统的性能和稳定性。
03
线程管理
线程的定义与状态
总结词
理解线程的定义和状态是线程管理的 基础。
详细描述
线程是操作系统中的基本执行单元, 具有独立执行的特性。根据其执行状 态,线程可分为就绪状态、阻塞状态 和运行状态。
线程的创建与终止
总结词
掌握线程的创建和终止方法是实现多线程程序的关键。
详细描述
线程可以通过系统调用或库函数创建,并为其分配资源。当线程完成其任务或 需要终止时,应正确地释放资源并结束线程。
产生条件
互斥条件、请求和保持条件、不剥夺 条件、环路等待条件。
操作系统课程设计报告
《操作系统课程设计》一、课程设计目的1、进程调度是处理机管理的核心内容。
2、本设计要求用C语言编写和调试一个简单的进程调度程序。
3、通过设计本可以加深理解有关进程控制块、进程队列的概念,并体会和了解最高优先数优先的调度算法(即把处理机分配给优先数最高的进程)和先来先服务算法的具体实施办法。
二、课程设计主要内容1、项目名称设计一个有 N个进程共行的进程调度程序2、实验设备及环境:软件要求:WINDOWS NT 系列操作系统,VC、VB、TURBO C等多种程序设计开发工具。
硬件要求:P4 2.0以上CPU、256M、40G硬盘。
3、课程设计类型综合设计型4、课程设计内容与要求1)进程调度算法:采用最高优先数优先的调度算法(即把处理机分配给优先数最高的进程)和先来先服务算法。
2)每个进程有一个进程控制块( PCB)表示。
进程控制块可以包含如下信息:进程名、优先数、到达时间、需要运行时间、已用CPU时间、进程状态等等。
3)进程的优先数及需要的运行时间可以事先人为地指定(也可以由随机数产生)。
进程的到达时间为进程输入的时间。
进程的运行时间以时间片为单位进行计算。
4)每个进程的状态可以是就绪 W(Wait)、运行R(Run)、或完成F(Finish)三种状态之一。
5)就绪进程获得 CPU后都只能运行一个时间片。
用已占用CPU时间加1来表示。
如果运行一个时间片后,进程的已占用 CPU 时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时应将进程的优先数减1(即降低一级),然后把它插入就绪队列等待CPU。
6)每进行一次调度程序都打印一次运行进程、就绪队列、以及各个进程的 PCB,以便进行检查。
7)重复以上过程,直到所要进程都完成为止。
5、课程设计方法及步骤1)充分了解各项设计要求。
深入理解有关进程控制块、进程队列的概念,并体会和了解最高优先数优先的调度算法(即把处理机分配给优先数最高的进程)和先来先服务算法的具体实施办法。
操作系统课程设计-对处理机的调度
课程设计报告课程名称:《操作系统》课程设计题目:对处理机的调度姓名:系:信息与机电工程系专业:计算机科学与技术年级:学号:指导教师:职称:2013年12月31日目录1设计目的 (4)2设计要求 (4)3设计方案 (4)3.1先到先服务算法 (4)3.2短进程优先算法 (6)4设计内容 (8)4.1输入进程信息 (8)4.2先到先服务算法输出 (9)4.3短进程优先算法输出 (9)5总结 (10)6参考文献 (10)对处理机的调度1.设计目的进程是操作系统最重要的概念之一,进程调度是操作系统内核的重要功能,本实验要求用C语言编写一个进程调度模拟程序,使用短作业优先调度算法,高响应比调度算法,先到先服务算法实现进程调度。
可以手动阻塞与唤醒。
本实验可加深对进程调度算法的理解。
在OS中,调度的实质是一种资源分配,调度算法即指:根据系统的资源分配策略所规定的资源分配算法。
对于不同的系统和系统目标,通常采用不同的调度算法,如在批处理系统中,为照顾为数众多的短作业,采用短作业有限调度算法;把当前处于就绪队列之首的那个进程调度到运行状态,采用先到先服务算法。
采用算法时,则要考虑多方面因素,以便达到最佳效果。
2.设计要求对处理机的调度设计一个有多个进程共行的进程调度程序。
进程调度算法:先到先服务算法,短作业优先调度算法每个进程有一个进程控制块( PCB)表示。
进程控制块可以包含如下信息:到达时间,服务时间,完成时间,周转时间,帯权周庄时间,平均周转时间,平均帯权周转时间。
int ArrivalTime[Max];//到达时间int ServiceTime[Max];//服务时间int FinishTime[Max];//完成时间int WholeTime[Max];//周转时间double WeightWholeTime[Max];//帯权周转时间double AverageWT_FCFS,AverageWT_SJF; //平均周转时间double AverageWWT_FCFS,AverageWWT_SJF;//平均帯权周转时间3.设计方案3.1 先到先服务算法采用先来先服务FCFS调度进程运行,计算每个进程的周转时间,带权周转时间,并且计算所有进程的平均周转时间,带权平均周转时间void FCFS()//找最早到达的。
操作系统1_处理机管理
V(s2)
…… }
V(s3)
…… }
}
经典进程的同步问题
The proceducer-consumer problem 生产者—消费者问题
抽象模型:生产者.消费者问题
一组生产者 (P1 , P2 ,......,Pk ) 一组消费者 (C1 , C2 ,......,Cm )
get
S1S3:buffer1. buffer2空
buffer1
buffer2
S1 : 空 1 S2 : 满 0
S3 : 空 1 S4 : 满 0
put
{…… P(s1)
copy {…… P(s2) P(s3)
get
{…… P(s4) 从buffer2 取数据
取数据
存入buffer1
取buffer1
四.信号量实现同步机制
解决“忙等待”
信号量S (Semaphore) 表示共享资源使用情况 仅被PV原子操作,P(S).V(S)访问
信号量:semaphore
定义如下: typedef struct { int value; PCBtype* queue; } semaphore; 信号量说明: semaphore s;
3)P.V操作的优缺点 优点: 简单,而且表达能力强(用P.V操作可解决
任何同步互斥问题)
缺点: 不够安全;P.V操作使用不当会出现死锁; 遇到复杂同步互斥问题时实现复杂
2.2.4 进程调度
一.调度类型:
高级(作业):后备队 列 创进程 就绪队列 剥夺 低级(进程) 非剥夺 中级(对换)
2.1.5 操作系统的特征
操作系统课程设计(设备管理)
操作系统课程设计(设备管理)目录一引言11.1课程设计题目11.2课程设计的目的11.3小组人数11.4编程语言11.5课程设计内容11.6界面设计如图1二课程设计任务及要求22.1设计任务22.2设计要求2三算法及数据结构23.1算法的总体思想(流程)23.2 Equipment模块33.2.1 功能33.2.2 数据结构33.3 cpu模块43.3.1 功能43.3.2 数据结构43.3.3 算法43.4 form1模块43.4.1 功能43.4.2 算法5四程序设计与实现54.1 程序流程图54.2 基本思想64.3 定义的公共变量或数据结构7 4.4 实验部分代码74.5 运行截图124.6使用说明15五总结15六参考文献15一引言1.1课程设计题目实现一个模拟操作系统。
1.2课程设计的目的通过模拟操作系统原理的实现,加深对操作系统工作原理理解,进一步了解操作系统的实现方法,并可练习合作完成系统的团队精神和提高程序设计能力。
1.3小组人数建议3~4人一组共同完成模拟系统的实现。
1.4编程语言建议使用VC、VB、C#、Java等Windows环境下的程序设计语言,以借助这些语言环境来模拟硬件的一些并行工作。
1.5课程设计内容模拟采用多道程序设计方法的单用户操作系统,该操作系统包括进程管理、存储管理、设备管理、文件管理和用户接口四部分。
1.6界面设计如图图1.1二课程设计任务及要求2.1设计任务设计一个设备管理分配程序,按先来先服务的算法,对设备进行分配。
2.2设计要求设备管理主要包括设备的分配和回收。
(1)模拟系统中有A、B、C三种独占型设备,A设备3个,B设备2个,C设备1个。
(2)因为模拟系统比较小,因此只要设备表设计合理即可。
(3)采用先来先服务分配策略,采用设备的安全分配方式。
(4)屏幕显示每个设备是否被使用,哪个进程在使用该设备,哪些进程在等待使用该设备。
三算法及数据结构3.1算法的总体思想(流程)设备管理的功能是按照设备的类型和系统采用的分配策略,为请求I/O进程分配一条传输信息的完整通路。
操作系统课程设计cpu管理
操作系统课程设计cpu管理一、教学目标本章节的教学目标是让学生掌握操作系统中CPU管理的基本原理和概念,了解CPU调度算法和进程管理的基本方法,培养学生分析和解决操作系统问题的能力。
1.理解进程和线程的概念及其关系。
2.掌握CPU调度算法的基本原理和分类。
3.了解进程同步和互斥的基本概念及实现方法。
4.理解虚拟处理器和时间片的概念。
5.能够使用相关工具对操作系统进行CPU性能分析。
6.能够根据实际需求设计简单的CPU调度算法。
7.能够分析并解决进程同步问题。
情感态度价值观目标:1.培养学生对操作系统CPU管理的兴趣,提高学生对计算机科学研究的热情。
2.培养学生团队协作和自主学习能力,提高学生分析问题和解决问题的能力。
二、教学内容本章节的教学内容主要包括CPU管理的基本原理、CPU调度算法、进程管理和虚拟处理器等。
1.CPU管理的基本原理:介绍进程和线程的概念及其关系,解释CPU调度算法的基本原理和分类。
2.CPU调度算法:讲解各种CPU调度算法的原理和实现方法,如先来先服务、最短作业优先、轮转等。
3.进程管理:介绍进程同步和互斥的基本概念,讲解进程同步的实现方法,如信号量、管程等。
4.虚拟处理器:解释虚拟处理器和时间片的概念,探讨虚拟处理器在操作系统中的应用。
三、教学方法为了提高学生的学习兴趣和主动性,本章节将采用多种教学方法,如讲授法、讨论法、案例分析法和实验法等。
1.讲授法:通过讲解CPU管理的基本原理、CPU调度算法、进程管理和虚拟处理器等内容,使学生掌握相关知识。
2.讨论法:学生分组讨论实际案例,培养学生的团队协作能力和解决问题的能力。
3.案例分析法:分析实际操作系统中的CPU管理案例,使学生更好地理解CPU管理的原理和应用。
4.实验法:安排实验课程,让学生亲自动手操作,提高学生的实践能力和创新能力。
四、教学资源本章节的教学资源包括教材、参考书、多媒体资料和实验设备等。
1.教材:选用权威、实用的操作系统教材,如《操作系统概念》等。
处理机管理
操作系统实习报告处理机管理一、实验内容处理机管理是操作系统中非常重要的部分。
为深入理解进程管理部分的功能,设计几个调度算法,模拟实现处理机的调度。
二、实验目的在多道程序或多任务系统中,系统同时处于就绪状态的进程有若干个。
为了使系统中的各进程有条不紊的进行,以选择一进程占用处理机。
要求学生设计一个模拟单处理机调度的算法,以巩固和加深处理机调度的概念。
三、实验题目:处理机管理源程序名:处理机调度.cpp执行程序名:处理机调度.exe数据结构:typedef struct node{char name[10]; /*进程标识符*/int prio; /*进程优先数*/int round; /*进程轮转时间片*/int cputime; /*进程占用CPU时间*/int arrivetime; /*进程到达时间*/int needtime; /*进程到完成还要的时间*/int count; /*计数器*/char state; /*进程的状态*/struct node *next; /*链指针*/}PCB;四、源程序:#include <stdio.h> /* 标准输入输出函数声明头文件*/#include <windows.h> /* system()函数声明头文件*/#include <conio.h> /* getch()函数的声明头文件*/typedef struct node{char name[10]; /*进程标识符*/int prio; /*进程优先数*/int round; /*进程轮转时间片*/int cputime; /*进程占用CPU时间*/int arrivetime; /*进程到达时间*/int needtime; /*进程到完成还要的时间*/int count; /*计数器*/char state; /*进程的状态*/struct node *next; /*链指针*/}PCB;PCB *run; /* 当前运行进程指针*/PCB *ready; /* 就绪队列头指针*/PCB *tail; /* 就绪队列尾指针*/PCB *finish; /* 完成队列头指针*/int iNumber; /*进程数*//////////////////////////////////////////////void FirstIn() /*将就绪队列中的第一个进程投入运行*/{run=ready; /*就绪队列头指针赋值给运行头指针*/run->state='R'; /*进程状态变为运行态*/ready=ready->next; /*就绪对列头指针后移到下一进程*/}/////////////////////////////////void PrintTitle(char a) /* 标题输出函数*/{if(toupper(a)=='P') /* toupper(int c):小写字符转换成大写优先数法*/ printf("进程名占用CPU时间还需要CPU时间优先数状态\n");if(toupper(a)=='R') /* 轮转法*/printf("进程名占用CPU时间还需要CPU时间计数器轮转时间片状态\n");if(toupper(a)=='C') /*先进先出法*/printf("进程名占用cpu时间还需要cpu时间到达时间状态\n");}//////////////////////////////////void PrintPCB(char cAlgo,PCB *q) /*进程PCB输出函数*/{if(toupper(cAlgo)=='P') /*优先数法的输出*/printf(" %-12s%-14d%-14d%-7d %c\n",q->name,q->cputime,q->needtime,q->prio,q->state );if(toupper(cAlgo)=='R') /*轮转法的输出*/printf(" %-12s%-14d%-14d%-10d%-10d %-c\n",q->name,q->cputime,q->needtime,q->cou nt,q->round,q->state);if(toupper(cAlgo)=='C')printf(" %-12s%-14d%-14d%-14d%-c\n",q->name,q->cputime,q->needtime,q->arrivetime, q->state);}/////////////////////////////////////////void Print(char cAlgo) /*输出主函数*/{PCB *p;PrintTitle(cAlgo); /*输出标题*/if(run!=NULL) /*如果运行指针不空*/PrintPCB(cAlgo,run); /*输出当前正在运行的PCB*/p=ready; /*输出就绪队列PCB*/while(p!=NULL){PrintPCB(cAlgo,p);p=p->next;}p=finish; /*输出完成队列的PCB*/while(p!=NULL){PrintPCB(cAlgo,p);p=p->next;}getch(); /*按任意键继续*/}/////////////////////////////////void Insert1(PCB *q)/*优先数调度的插入函数,将还未完成且优先数小于别的进程PCB按优先数非递增顺序插入到就绪队列*/{PCB *pcbPF,*pcbP,*pcbS;int iFlag;pcbS=q; /*待插入的PCB指针*/pcbP=ready; /*就绪队列头指针*/pcbPF=pcbP; /*pcbPF做pcbP的前驱指针*/iFlag=1; /*结束标志,找到插入位置后iFlag变为0*/while((pcbP!=NULL) && iFlag) /*根据优先数确定插入位置*/if(pcbP->prio >= pcbS->prio) /*如果就绪队列中的优先数比待插入的优先数要大或者相等*/{pcbPF=pcbP;pcbP=pcbP->next;}elseiFlag=0;if(pcbPF!=pcbP) /*如果条件成立说明插入在pcbPF与pcbP之间*/{pcbPF->next=pcbS;pcbS->next=pcbP;}else /*否则插入在就绪队列的头*/{pcbS->next=pcbP;ready=pcbS;}}///////////////////////////////////////////////////void Insert2(PCB *pcbP)/*轮转法调度的插入函数,将执行了一个单位时间片数且还未完成的进程的PCB插入到就绪队列的队尾*/{tail->next=pcbP; /*将新的PCB插入在当前就绪队列的尾*/tail=pcbP;pcbP->next=NULL;}///////////////////////////////////////////////////void Insert3(PCB *q)/*先来先服务调度插入函数,将到达的进程的PCB插入到就绪队列的队尾*/{PCB *pcbPF,*pcbP,*pcbS;int iFlag;pcbS=q; /*待插入的PCB指针*/pcbP=ready; /*就绪队列头指针*/pcbPF=pcbP; /*pcbPF做pcbP的前驱指针*/iFlag=1; /*结束标志,找到插入位置后iFlag变为0*/while((pcbP!=NULL) && iFlag) /*根据到达时间确定插入位置*/ if(pcbP->arrivetime<= pcbS->arrivetime) /*如果就绪队列中的到达时间比待插入的到达时间要小或者相等*/{pcbPF=pcbP;pcbP=pcbP->next;}elseiFlag=0;if(pcbPF!=pcbP) /*如果条件成立说明插入在pcbPF与pcbP之间*/{pcbPF->next=pcbS;pcbS->next=pcbP;}else /*否则插入在就绪队列的头*/{pcbS->next=pcbP;ready=pcbS;}}////////////////////////////////////////////////void CreatePrio(char cAlgo) /*优先数创建初始PCB信息*/{PCB *pcbP;int i,iPrio,iTime;char cName[10];ready=NULL; /*就绪队列头指针*/finish=NULL; /*完成队列头指针*/run=NULL; /*运行队列指针*/printf("你选择了以优先数调度算法(Priority)进行模拟处理机调度,下面将创建PCB信息:\n\n");for(i=1;i<=iNumber;i++){if(1==iNumber){printf("请输入进程的进程名、优先数和所需cpu时间:\n"); /*输入进程标识、优先数和所需CPU时间创建PCB*/}else{printf("请输入第%d个进程的进程名、优先数和所需cpu时间:\n",i); /*输入进程标识、优先数和所需CPU时间创建PCB*/}pcbP=(PCB*)malloc(sizeof(PCB));scanf("%s",&cName);scanf("%d",&iPrio);scanf("%d",&iTime);strcpy(pcbP->name,cName);pcbP->prio=iPrio; /* 初始化进程优先数*/pcbP->cputime=0; /* 初始占用CPU时间为0 */pcbP->needtime=iTime; /* 初始还需要CPU时间为总的所需时间*/pcbP->state='W'; /* 进程初始为"w"就绪(等待)状态*/if(ready!=NULL) /* 就绪队列不空调用插入函数插入*/Insert1(pcbP);else{pcbP->next=ready; /* 创建就绪队列的第一个PCB */ready=pcbP;}}system("cls"); /*清屏*/printf("\n\t 进程控制块(PCB)的信息如下:\n");printf("------------------------------------------------------\n");Print(cAlgo); /*输出进程PCB信息*/run=ready; /*将就绪队列的第一个进程投入运行*/ready=ready->next;run->state='R'; /* "R"表示运行状态*/}//////////////////////////////////////////void CreateRound(char cAlgo) /*轮转法创建初始PCB信息*/{PCB *pcbP;int i,iTime,iRound;char cName[10];ready=NULL; /*就绪队列头指针*/finish=NULL; /*完成队列头指针*/run=NULL; /*运行队列指针*/printf("你选择了以时间片轮转调度算法(Roundrobin)进行模拟处理机调度,下面将创建PCB信息:\n\n");for(i=1;i<=iNumber;i++){if(1==iNumber){printf("请输入进程的进程名、轮转时间片和所需cpu时间:\n"); /*输入进程标识、优先数和所需CPU时间创建PCB*/}else{printf("请输入第%d个进程的进程名、轮转时间片和所需cpu时间:\n",i); /*输入进程标识、优先数和所需CPU时间创建PCB*/}pcbP=(PCB*)malloc(sizeof(PCB));scanf("%s",&cName);scanf("%d",&iRound);scanf("%d",&iTime);strcpy(pcbP->name,cName);pcbP->round=iRound; /* 初始进程轮转时间片数*/pcbP->cputime=0; /* 初始占用CPU时间为0 */pcbP->needtime=iTime; /* 初始还需要CPU时间为总的所需时间*/pcbP->count=0; /* 计数器初始化为0 */pcbP->state='W'; /* 进程初始为"w"就绪(等待)状态*/if(ready!=NULL)Insert2(pcbP);else{pcbP->next=ready;ready=pcbP;tail=pcbP;}}system("cls");printf("\n\t\t进程控制块(PCB)的信息如下:\n");printf("-------------------------------------------------------------------\n");Print(cAlgo); /*输出进程PCB信息*/run=ready; /*将就绪队列的第一个进程投入运行*/ready=ready->next;run->state='R';}//////////////////////////////////////////void CreateFCFS(char cAlgo) /*先来先服务法创建初始PCB信息*/{PCB *pcbP;int i,iTime,iArrive;char cName[10];ready=NULL; /*就绪队列头指针*/finish=NULL; /*完成队列头指针*/run=NULL; /*运行队列指针*/printf("你选择了以先来先服务调度算法(Roundrobin)进行模拟处理机调度,下面将创建PCB信息:\n\n");for(i=1;i<=iNumber;i++){if(1==iNumber){printf("请输入进程的进程名、到达时间和所需cpu时间:\n"); /*输入进程标识、优先数和所需CPU时间创建PCB*/}else{printf("请输入第%d个进程的进程名、到达时间和所需cpu时间:\n",i); /*输入进程标识、优先数和所需CPU时间创建PCB*/}pcbP=(PCB*)malloc(sizeof(PCB));scanf("%s",&cName);scanf("%d",&iArrive);scanf("%d",&iTime);strcpy(pcbP->name,cName);pcbP->arrivetime=iArrive; /* 初始进程轮转时间片数*/pcbP->cputime=0; /* 初始占用CPU时间为0 */pcbP->needtime=iTime; /* 初始还需要CPU时间为总的所需时间*/pcbP->state='W'; /* 进程初始为"w"就绪(等待)状态*/if(ready!=NULL)Insert3(pcbP);else{pcbP->next=ready;ready=pcbP;tail=pcbP;}}system("cls");printf("\n\t\t进程控制块(PCB)的信息如下:\n");printf("-------------------------------------------------------------------\n");Print(cAlgo); /*输出进程PCB信息*/run=ready; /*将就绪队列的第一个进程投入运行*/ready=ready->next;run->state='R';}///////////////////////////////////////////void PriSch(char cAlgo) /*优先数调度算法*/{while(run != NULL) /*当运行队列不空时,有进程正在运行*/{run->cputime=run->cputime+1; /*每运行一次CPU时间片数加1个单位*/run->needtime=run->needtime-1; /*每运行一次进程还需要的时间片数减1个单位*/run->prio=run->prio-1; /*每运行一次优先数减去1个单位*/if(0==run->needtime) /*如所需时间为0将其插入完成队列*/{run->state='F'; /*置状态为完成态*/run->next=finish; /*插入在完成队列的队头*/finish=run;run=NULL; /*运行队列头指针为空*/if(ready!=NULL) /*如就绪队列不空*/FirstIn(); /*将就绪对列的第一个进程投入运行*/}else /*没有运行完同时优先数不是最大,则将其变为就绪态插入到就绪队列*/if((ready!=NULL) && (run->prio < ready->prio)){run->state='W'; /*置状态为就绪态*/Insert1(run); /*调用插入函数将该PCB插入到就绪队列队尾*/FirstIn(); /*将就绪队列的第一个进程投入运行*/}Print(cAlgo); /*输出进程此时的各进程PCB信息*/ }}///////////////////////////////////////////void RoundSch(char cAlgo) /*时间片轮转调度算法*/{while(run!=NULL){run->cputime=run->cputime+1; /* 每运行一次CPU时间片数加1个单位*/run->needtime=run->needtime-1; /* 每运行一次进程还需要的时间片数减1个单位*/run->count=run->count+1; /* 每运行一次计数器加1个单位*/if(0==run->needtime) /*如所需时间为0将其插入完成队列*/{run->state='F'; /* 将状态变为完成态*/run->next=finish; /*插入到完成队列的队头*/finish=run;run=NULL;if(ready!=NULL)FirstIn(); /*就绪对列不空,将第一个进程投入运行*/ }elseif(run->count==run->round) /*如果时间片到*/{run->count=0; /*计数器置0*/if(ready!=NULL) /*如就绪队列不空*/{run->state='W'; /*置状态为就绪态*/Insert2(run); /*调用插入函数将该PCB插入到就绪队列队尾,等待轮转*/FirstIn(); /*将就绪对列的第一个进程投入运行*/}}Print(cAlgo); /*输出此时的各进程PCB信息*/ }}//////////////////////////////////////////////////void FCFSSch(char cAlgo) /*先来先服务调度算法*/{while(run!=NULL){run->cputime=run->cputime+1; /* 每运行一次CPU时间片数加1个单位*/run->needtime=run->needtime-1; /* 每运行一次进程还需要的时间片数减1个单位*/if(0==run->needtime) /*如所需时间为0将其插入完成队列*/{run->state='F'; /* 将状态变为完成态*/run->next=finish; /*插入到完成队列的队头*/finish=run;run=NULL;if(ready!=NULL)FirstIn(); /*就绪对列不空,将第一个进程投入运行*/ }Print(cAlgo);}}//////////////////////////////////////////////////int main()/*主函数*/{char cAlgo; /*算法标记*/char cFlag='Y';while(toupper(cFlag)=='Y'){system("cls");printf("\t======================================\n");printf("\t 操作系统课程设计---模拟处理机调度\n");printf("\t 作者:冯敏\n");printf("\t 时间:2007年12月14日\n");printf("\t copyright(c) All Rights Reserved \n");printf("\t=======================================\n");printf("请键入字母P或者R进行算法选择:P(Priority) / R(Roundrobin) / C(FCFS)\n_");scanf("%c",&cAlgo); /*输入字符确定算法*/if(toupper(cAlgo)=='P' || toupper(cAlgo)=='R' || toupper(cAlgo)=='C'){printf("\n请输入要创建的进程个数:Number=");scanf("%d",&iNumber); /*输入进程数*/while(iNumber<=0){printf("进程个数不能为0或负数!\n_");scanf("%d",&iNumber);}if(cAlgo=='P'||cAlgo=='p'){system("cls");CreatePrio(cAlgo); /*优先权调度*/PriSch(cAlgo);getchar();printf("\n进程已全部运行完毕,是否要继续操作?(Y/N): ");scanf("%c",&cFlag);}if(cAlgo=='R'||cAlgo=='r'){system("cls");CreateRound(cAlgo); /*时间片轮转调度*/RoundSch(cAlgo);getchar();printf("\n进程已全部运行完毕,是否要继续操作?(Y/N): ");scanf("%c",&cFlag);}if(cAlgo=='C'||cAlgo=='c'){system("cls");CreateFCFS(cAlgo);/*先来先服务调度*/FCFSSch(cAlgo);getchar();printf("\n进程已全部运行完毕,是否要继续操作?(Y/N): ");scanf("%c",&cFlag);}}}return 1;}五、打印程序运行时的初值与运行结果,要求如下:1、各进程控制块的初始状态;2、选中运行进程的名,运行后各进程控制块状态以及每次调度时,就绪队列的进程排列顺序。
操作系统第四章处理机管理
2. FCFS的特点
• 比较有利于长作业,而不利于短作业。 • 有利于CPU繁忙的作业,而不利于I/O繁
忙的作业。
实例
作业号 1 2 3
提交时间 10:00 10:06 10:15
运行长度 2小时 1小时 0.25小时
• 仅当较高优先级的队列为空,才调度较低优先级的 队列中的进程执行。如果进程执行时有新进程进入 较高优先级的队列,则抢先执行新进程,并把被抢 先的进程投入原队列的末尾。
2. 几点说明
• I/O型进程:让其进入最高优先级队列,以及时响应 I/O交互。通常执行一个小时间片,要求可处理完一 次I/O请求的数据,然后转入到阻塞队列。
4.3.4 多级反馈队列算法 (Round Robin with Multiple Feedback)
• 多级反馈队列算法是时间片轮转算法和 优先级算法的综合和发展。优点:
– 为提高系统吞吐量和缩短平均周转时间而照 顾短进程。
– 为获得较好的I/O设备利用率和缩短响应时 间而照顾I/O型进程。
1. 多级反馈队列算法
表4.2 三个作业计算结果
作业号
开始时间
结束时间
周转时间
1
10:00
12:00
2.00小时
2
12:00
13:00
2.90小时
3
13:00
13:15
3.00小时
4.2.2 短作业优先 (SJF, Shortest Job First)
又称为“短进程优先”SPN(Shortest Process Next); 这是对FCFS算法的改进,其目标是减少平均周转时 间。
处理机管理
原语的执行过程是不可中断的。
创建原语 撤销原语 阻塞原语 唤醒原语
一、创建原语:
实质是创建进程控制块
1
申请空闲 PCB
2
向 PCB 填入信息
3
设置进程为就绪状态
4
进程创建步骤
进程进入就绪队列
二、撤销原语
顺序执行
x =3
x =1
顺
y=x+2
y=x+5
序
执
printf(y)
printf(y) 行
t1
t2
t3
t4
t5
t6
结果: y = 5
y=6
并发执行(一)
并
发
x =3
执
x =1
y=x+2
行
y=x+5
printf(y) printf(y)
t1
t2
t3
t4
t5
t6
结果: y = 3
y=3
并发执行(二)
优先级算法
静态优先级算法 动态优先级算法
A. 静态优先级算法
进程的优先级在进程创建时确定,不再更改。
算法简单 系统开销相对动态优先级小 低优先级进程可能得不到调度
B. 动态优先级算法
在创建进程时确定一个基本优先级,在进 程执行过程中按照一定原则动态改变。
* 就绪等待进程优先级随等待时间增加而升高 * 执行进程的优先级随CPU占用时间增加而下降
前驱图
有向无环图 节点:表示一条语句,或一段程序 有向线段:表示语句之间的顺序关系 无环:当程序中出现循环时,一般将整个 循环作为一个节点
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
操作系统课程设计题目:处理机管理学生姓名:X X X学院:信息工程学院系别:计算机系专业:软件工程班级:软件09-1指导教师:X X X教授X X X教授2011年12月30日XXX大学课程设计任务书学院(系):课程名称:操作系统课程设计指导教师(签名):专业班级:软件工程 09-1 学生姓名: XXX 学号: XXXXXXXXX目录第一章系统概述 (1)1.1 功能简介 (1)1.2 设计思路 (1)第二章系统功能分析和设计 (2)2.1 系统主要结构模块 (2)2.2 创建进程队列功能 (2)2.3 对进程排序 (3)2.4 输出所创建的信息 (5)第三章调试及运行结果 (6)3.1 输入界面 (6)3.2 输出界面 (6)3.3 运行结果 (6)3.4 各种情况的运行结果 (7)第四章总结 (9)4.1 遇到的问题以及解决方法 (9)4.2 收获和体会 (9)参考文献: (10)附录程序源代码 (11)第一章系统概述1.1 功能简介处理机调度是操作系统中非常重要的部分。
在多道程序设计系统中,内存中有多道程序运行,他们相互争夺处理机这一重要的资源。
处理机调度就是从就绪队列中,按照一定的算法选择一个进程并将处理机分配给它运行,以实现进程并发地执行。
本系统就是设计了一个模拟单处理机调度的算法,以模拟实现处理机调度的基本功能。
本系统是采用时间片轮转算法模拟单处理机调度。
1.2 设计思路系统将所有的就绪进程按先来先服务的原则排成一个队列,每次调度时,把CPU分配给队首进程,并令其执行一个时间片。
时间片的大小由输入确定。
当执行的时间片用完时,由一个计时器发出时钟中断请求,调度程序便据此信号来停止该进程的执行,并将它送往就绪队列的末尾;然后,再把处理机分配给就绪队列中的队首进程,同时也让它执行一个时间片。
这样就可以保证就绪队列中的所有进程在一给定的时间内获得一时间片的处理机执行时间。
换言之,系统能在给定的时间内响应所有用户的请求。
每个进程用一个进程控制块PCB来代表。
PCB的格式如图1-1所示。
图1-1 进程控制块其中,进程名即进程标识。
第二章系统功能分析和设计在本章中,主要是介绍各个功能函数的设计思路和实现方法。
2.1 系统主要结构模块本系统主要分为:主函数,创建进程队列函数,对进程队列按到达时间进行排序,输出所创建的进程信息,执行时间片调度算法。
在程序执行过程中通过主函数调用各个子函数来一次实现系统的各个功能。
系统主要结构模块如图2-1:图2-1 程序结构模块2.2 创建进程队列功能在此函数中输入所要创建进程的总个数n,然后再通过for循环语句来控制,依次输入各个进程的属性值,再把刚创建的进程加入进程就绪队列的队尾,循环上述操作n次。
其中,在创建进程的过程中,进程的状态默认为就绪状态s,指向下一进程的指针默认为空NULL。
程序流程图如图2-2所示:图2-2 创建进程队列2.3 对进程排序此函数的主要功能就是:按照进程的到达时间进行升序排序,在该函数中采用的排序方法是冒泡排序法。
程序流程图如图2-3所示:2.4 输出所创建的信息此函数所实现的主要功能就是:按照进程的到达时间依次输出各个进程的详细信息。
再此函数中,首先定义一个进程控制块指针,指向进程队列中的第一个节点,通过while语句(当p!=NULL时)来控制p=p->next循环,依次输出进程就绪队列中的各进程的详细信息。
流程图如图2-4所示:图2-4 输出所创建的进程信息第三章调试及运行结果3.1 输入界面在此,先输入要创捷的进程总数,然后依次输入各进程的进程名、到达时间、估计运行时间,如图3-1所示:图3-1 输入界面3.2 输出界面此界面是,输出经过排序后的进程队列,如图3-2所示:图3-2 输出界面3.3 运行结果输出经过时间片轮转算法后的运行结果,如图3-3所示:图3-3运行结果3.4 各种情况的运行结果下图是各种不同情况的运行结果,如图3-4,图3-5,图3-6:图3-4 运行结果图3-5 运行结果图3-6 运行结果第四章总结4.1 遇到的问题以及解决方法首先,是对时间片算法以及处理机的具体调度过程不够熟练,通过看书和搜集一些资料解决了这个问题;其次,是在对单链表按到达时间进行排序时遇到了一些麻烦,后来经过认真思考与分析,成功地对单链表进行了排序;最后,是在编写程序的过程中出现了一些语法错误,后通过调试逐一解决。
4.2 收获和体会此次操作系统课程设计,在指导教师的精心教导下,以及同学们的积极讨论中,对处理机的调度问题有了深刻的理解和认识,同时对其它的几个题目也有了一定的了解。
首先要对程序的设计要求有一个比较明确的认识,然后系统分析与系统设计,最后是代码设计与调试。
根据操作系统课程所学的概念、理论和方法,按照程序设计的基本步骤,设计出一个适当规模的程序;进一步加深了对处理机调度问题的理解和掌握。
理论联系实际,加深和巩固所学的理论知识,提高实践能力和计算机的综合运用能力。
我们编写程序的过程是辛苦与快乐的,程序的编写原则很重要,只要我们在编程,就必须不断改进,才能更好提高实践编程能力。
参考文献:[1] 张尧学主编.计算机操作系统教程(第三版).北京:清华大学出版社,2006[2] 张尧学编.计算机操作系统教程(第三版)习题解答与实验指导.北京:清华大学出版社,2006[3] 汤子瀛主编.计算机操作系统(第三版).西安:西安电子科技大学出版社,2001[4] 张坤等编.操作系统实验教程.北京:清华大学出版社,2008[5] 张丽芬等编.操作系统实验教程.北京:清华大学出版社,2006[6] 屠祁等编.操作系统基础(第三版).北京:清华大学出版社,2000[7] 冯耀霖等编.操作系统.西安:西安电子科技大学出版社,2001[8] 左万历.计算机操作系统教程(第二版).北京:高等教育出版社,2004附录程序源代码#include<stdio.h>#include<string.h>#include<stdlib.h>//定义进程控制块//typedef struct pcb{char pname[20]; //进程名int arrivetime; //到达时间int runtime; //运行时间char state; //运行后的状态struct pcb *next;}PCB;//封装头结点,指针分别指向队头和队尾//typedef struct{PCB *front,*rear;}queue;//进程队列置空//queue *init(){queue *head;head=(queue*)malloc(sizeof(queue));head->front=NULL;head->rear=NULL;return head;}//检验进程队列是否为空//int empty(queue *head){return(head->front ? 0:1);}//进程队列入队,往后插入//queue *append(queue *head,char c[20],int a,int r,char s) {PCB *p;p=(PCB*)malloc(sizeof(PCB));strcpy(p->pname,c);p->arrivetime=a;p->runtime=r;p->state=s;p->next=NULL;if(empty(head))head->front=head->rear=p;else{head->rear->next=p;head->rear=p;}return head;}//创建进程队列//queue *creat(queue *head){char c[20];char s='R';int a,r,i,n;printf("请输入共有几个进程:\n");scanf("%d",&n);for(i=1;i<=n;i++){printf("请分别输入第%d个进程的进程名、到达时间、估计运行时间:\n",i);scanf("%s%d%d",c,&a,&r);head=append(head,c,a,r,s);}return head;}//按到达时间排序//queue *sort(queue *head){PCB *h,*p,*r1,*r2,*min=head->front,*max=head->front;int flag;h=(PCB*)malloc(sizeof(PCB));h->next = head->front ;while (1){flag=0;for (p=h;p->next->next!=NULL;p=p->next){r1=p->next;r2=p->next->next;if (r1->arrivetime > r2->arrivetime){if(r2->arrivetime < min->arrivetime) min=r2;if(r1->arrivetime > max->arrivetime) max=r1;flag=1;p->next=r2;r1->next=r2->next;r2->next=r1;}}if (flag==0)break;}head->front=min; head->rear=max;h->next=head->front;return head;}//输出创建的进程队列//void print(queue *head){PCB *p;p=head->front;if(!p)printf("时间片轮转调度队列为空!\n");while(p){printf("pname=%s arrivetime=%d runtime=%d state= %c",p->pname,p->arrivetime,p->runtime,p->state);printf("\n");p=p->next;}}//时间片轮转调度算法的实现//void RR(queue *head,int q){int t=head->front->arrivetime,lt=head->rear->arrivetime;if(head->front->runtime<q)t=t+head->front->runtime;elset=t+q;//进程队列不为空才可调度//while(!empty(head)){PCB *p1,*p2;/* 第一种情况:当前运行的时间小于最后一个进程到达的时间做以下操作*/while(t<lt){p1=head->front;printf("运行的时刻为%d\t运行的进程为%s\t",t,p1->pname);p1->runtime=p1->runtime-q;// 1. 运行时间小于0,删除队首//if(p1->runtime<=0){p1->state='C';printf("运行后的状态为%c\n",p1->state);head->front=p1->next;free(p1);}// 2. 运行时间大于0,向后找位置插入//else{printf("运行后的状态为%c\n",p1->state);p2=p1->next;while(p2->next&&p2->arrivetime!=t){ p2=p2->next;}/*此时无新进入队列的进程时,有两种情况:1.不用找位置往后插入,队首不变,不做操作2.找位置往后插入*/if(p2->arrivetime!=t){PCB *p3=p1,*p4;while(p3->next&&p3->arrivetime<t){p4=p3;p3=p3->next;}if(p3->arrivetime>t){if(p4!=p1)//p1插在p4后,头为p1->next{head->front=p1->next;p1->next=p4->next;p4->next=p1;}else//不做操作//p4=p3=p2=NULL;}elsep4=p3=p2=NULL;}//此时有新进入队列的进程时:p1插在新进入队列的进程p2后,队首为p1->next// else{head->front=p1->next;p1->next=p2->next;p2->next=p1;}}/*时刻变化*/if(head->front->runtime<q)t=t+head->front->runtime;elset=t+q;}//第一种情况结束///* 第二种情况:当前运行的时间大于最后一个进程到达的时间做以下操作*/while(t>=lt){p1=head->front;printf("运行的时刻为%d\t运行的进程为%s\t",t,p1->pname);p1->runtime=p1->runtime-q;// 1. 运行时间小于0,删除队首//if(p1->runtime<=0){p1->state='C';printf("运行后的状态为%c\n",p1->state);head->front=p1->next;free(p1);}// 2. 运行时间大于0,直接插在队尾//else{printf("运行后的状态为%c\n",p1->state);//若原队列只有一个进程,不必往队尾插//if(!p1->next) head->front=p1;//若原队列有多个进程//else{head->front=p1->next;head->rear->next=p1;head->rear=p1;p1->next=NULL;}}/*时刻变化,队列为空时不做时刻变化*/if(empty(head)) return;else{if(head->front->runtime<q)t=t+head->front->runtime;elset=t+q;}}//第二种情况结束//}}void main(){queue *head;int q;head=init();head=creat(head);head=sort(head);printf("您输入的时间片轮转进程队列为:\n");print(head);printf("请输入时间片轮转调度的时间片为:\n");scanf("%d",&q);RR(head,q);}。