操作系统实验三进程调度
操作系统实验,实验3, 进程管理 (1)

在图形界面上利用终端通过命令“su - ”切换到超级用户,编辑文件 “job”; 按组合键[Ctrl+Alt+F2]切换到第二个虚拟终端(超级用户); 输入命令“at –f job now+1 minute”,设置1分钟后执行at调度内容; 稍等后观察at调度的执行效果,再切换到第一个虚拟终端观察at调度 的执行效果;
切换到第一个虚拟终端观察at调度的执行效果(5分钟后系统将执行重 启调度任务)。
[操作要求2] 设置一个调度,要求1分钟后执行文件job中的作业。 文件job的内容为: find /home/jkx/ -name “*.c” > /home/jkx/fdresult wall user jkx, all code files have been searched out! Please check out. [操作步骤]
续表
守 护 进 程 innd Usenet新闻服务器 功 能 说 明
linuxconf
lpd named netfs network
允许使用本地WEB服务器作为用户接口来配置机器
打印服务器 DNS服务器 安装NFS、Samba和NetWare网络文件系统 激活已配置网络接口的脚本程序
nfsd
portmap postgresql routed sendmail
事件(例如xinetd和lpd)
启动守护进程有如下几种方法
在引导系统时启动 人工手动从shell提示符启动
系统启动script的执行期间 被启动(/etc/rc.d) 任何具有相应执行 权限的用户
使用crond守护进程启动
执行at命令启动
守护进程一般由系统在开机时通过脚本或root
操作系统实验报告进程调度

操作系统实验报告进程调度操作系统实验报告:进程调度引言在计算机科学领域中,操作系统是一个重要的概念,它负责管理和协调计算机系统中的各种资源,包括处理器、内存、输入/输出设备等。
其中,进程调度是操作系统中一个非常重要的组成部分,它负责决定哪个进程在何时获得处理器的使用权,以及如何有效地利用处理器资源。
实验目的本次实验的目的是通过对进程调度算法的实验,深入理解不同的进程调度算法对系统性能的影响,并掌握进程调度算法的实现方法。
实验环境本次实验使用了一台配备了Linux操作系统的计算机作为实验平台。
在该计算机上,我们使用了C语言编写了一些简单的进程调度算法,并通过模拟不同的进程调度场景进行了实验。
实验内容1. 先来先服务调度算法(FCFS)先来先服务调度算法是一种简单的进程调度算法,它按照进程到达的顺序进行调度。
在本次实验中,我们编写了一个简单的FCFS调度算法,并通过模拟多个进程同时到达的情况,观察其对系统性能的影响。
2. 短作业优先调度算法(SJF)短作业优先调度算法是一种根据进程执行时间长度进行调度的算法。
在本次实验中,我们编写了一个简单的SJF调度算法,并通过模拟不同长度的进程,观察其对系统性能的影响。
3. 时间片轮转调度算法(RR)时间片轮转调度算法是一种按照时间片大小进行调度的算法。
在本次实验中,我们编写了一个简单的RR调度算法,并通过模拟不同时间片大小的情况,观察其对系统性能的影响。
实验结果通过实验,我们发现不同的进程调度算法对系统性能有着不同的影响。
在FCFS 算法下,长作业会导致短作业等待时间过长;在SJF算法下,长作业会导致短作业饥饿现象;而RR算法则能够较好地平衡不同进程的执行。
因此,在实际应用中,需要根据具体情况选择合适的进程调度算法。
结论本次实验通过对进程调度算法的实验,深入理解了不同的进程调度算法对系统性能的影响,并掌握了进程调度算法的实现方法。
同时,也加深了对操作系统的理解,为今后的学习和研究打下了良好的基础。
操作系统实验报告进程调度

操作系统实验报告进程调度操作系统实验报告:进程调度引言操作系统是计算机系统中最核心的软件之一,它负责管理和调度计算机的资源,提供良好的用户体验。
在操作系统中,进程调度是其中一个重要的功能,它决定了进程的执行顺序和时间片分配,对于提高计算机系统的效率和响应能力至关重要。
本篇实验报告将重点介绍进程调度的相关概念、算法和实验结果。
一、进程调度的概念进程调度是操作系统中的一个重要组成部分,它负责决定哪个进程可以使用CPU,并为其分配执行时间。
进程调度的目标是提高系统的吞吐量、响应时间和公平性。
在多道程序设计环境下,进程调度需要考虑多个进程之间的竞争和协作,以实现资源的合理利用。
二、进程调度算法1. 先来先服务调度(FCFS)先来先服务调度算法是最简单的进程调度算法之一,它按照进程到达的顺序进行调度,即先到达的进程先执行。
这种算法的优点是公平性高,缺点是无法适应长作业和短作业混合的情况,容易产生"饥饿"现象。
2. 最短作业优先调度(SJF)最短作业优先调度算法是根据进程的执行时间来进行调度的,即执行时间最短的进程先执行。
这种算法的优点是能够最大程度地减少平均等待时间,缺点是无法适应实时系统和长作业的情况。
3. 时间片轮转调度(RR)时间片轮转调度算法是一种抢占式调度算法,它将CPU的执行时间划分为固定大小的时间片,并按照轮转的方式分配给各个进程。
当一个进程的时间片用完后,它将被挂起,等待下一次调度。
这种算法的优点是能够保证每个进程都能够获得一定的执行时间,缺点是无法适应长作业和短作业混合的情况。
4. 优先级调度(Priority Scheduling)优先级调度算法是根据进程的优先级来进行调度的,优先级高的进程先执行。
这种算法的优点是能够根据进程的重要性和紧急程度进行灵活调度,缺点是可能会导致低优先级的进程长时间等待。
三、实验结果与分析在实验中,我们使用了不同的进程调度算法,并对其进行了性能测试。
操作系统实验三 时间片轮转法完成进程调度

实验三:时间片轮转法完成进程调度一、实验目的:(1)加深对进程的理解(2)理解进程控制块的结构(3)理解进程运行的并发性(4)掌握时间片轮转法进程调度算法实验内容:(1)建立进程控制块(2)设计三个链队列,分别表示运行队列、就绪队列和完成队列(3)用户输入进程标识符以及进程所需的时间,申请空间存放进程PCB信息。
(4)每一个时间片结束输出各进程的进程号,CPU时间(即已经占用的CPU时间),所需时间(即还需要的CPU时间),以及状态(即用W表示等待,R表示运行,F表示完成)实验程序:#include <stdio.h>#include <stdlib.h>#include <string.h>typedef struct node{char name[10];/*进程标识符*/int prio;/*进程优先数*/int round;/*进程时间轮转时间片*/int cputime; /*进程占用CPU时间*/int needtime; /*进程到完成还要的时间*/int count;/*计数器*/char state; /*进程的状态*/struct node *next; /*链指针*/}PCB;PCB *finish,*ready,*tail,*run; //队列指针int N,t; //进程数,时间片的大小void firstin(){run=ready;//就绪队列头指针赋值给运行头指针run->state='R'; //进程状态变为运行态ready=ready->next; //就绪队列头指针后移到下一进程}void prt1(char a)//输出标题函数{if(toupper(a)=='P')//优先级法printf("进程名占用CPU时间到完成还要的时间轮转时间片状态\n");} void prt2(char a,PCB *q)//进程PCB输出{if(toupper(a)=='P')//优先级法的输出printf("%4s %8d %12d %14d %8c\n",q->name,q->cputime,q->needtime,q->roun d,q->state);}void prt(char algo)//输出函数二、三、{PCB *p;prt1(algo);//输出标题if(run!=NULL)//如果运行指针不空prt2(algo,run);//输出当前正在运行的PCBp=ready;//输出就绪队列PCBwhile(p!=NULL){prt2(algo,p);p=p->next;}p=finish;//输出完成队列的PCBwhile(p!=NULL){prt2(algo,p);p=p->next;}getchar(); //按住任意键继续}void insert(PCB *q)//时间片轮转的插入算法{PCB *p1,*s,*r;s=q;//待插入的PCB指针p1=ready;//就绪队列头指针r=p1;//*r做pl的前驱指针while(p1!=NULL)if(p1->round<=s->round){r=p1;p1=p1->next;}if(r!=p1){r->next=s;s->next=p1;}else{s->next=p1;//否则插入在就绪队列的头ready=s;}}void create(char alg)//时间片轮转法创建链表进程PCB{PCB *p;int i,time;char na[10];ready=NULL;finish=NULL;run=NULL;printf("输入进程名及其需要运行的时间(中间以空格隔开):\n"); for(i=1;i<=N;i++){p=new PCB;scanf("%s %d",&na,&time);strcpy(p->name,na);p->cputime=0;p->needtime=time;p->state='W';//进程的状态p->round=0;if(ready!=NULL)insert(p);else{p->next=ready;ready=p;}}printf("*************时间片轮转法进程调度过程*************\n"); prt(alg);run=ready;ready=ready->next;run->state='R';}void timeslicecycle(char alg)//时间片轮转法{while(run!=NULL){run->cputime=run->cputime+t;//处理时间加trun->needtime=run->needtime-t;//完成需要时间减trun->round=run->round+t;//运行完将其变为完成态,插入完成队列if(run->needtime<=0)//当进程完成时{run->next=finish;finish=run;run->state='F';run=NULL;if(ready!=NULL)//就绪队列不空,将第一个进程投入进行firstin();}else{run->state='W';//将进程插入到就绪队列中等待轮转insert(run);//将就绪队列的第一个进程投入运行firstin();}prt(alg);}}void main()//主函数{char algo='P';//算法标记printf("输入进程的个数:");scanf("%d",&N);//输入进程数printf("定义时间片大小:");scanf("%d",&t);//输入时间片大小create(algo);//创建进程timeslicecycle(algo);//时间片轮转法调度}//main()四、实验结果:五、实验小结:时间片轮转调度是一种最古老,最简单,最公平且使用最广的算法。
电大操作系统实验报告3_ 进程管理实验

电大操作系统实验报告3_ 进程管理实验电大操作系统实验报告 3 进程管理实验一、实验目的进程管理是操作系统的核心功能之一,本次实验的目的是通过实际操作和观察,深入理解进程的概念、状态转换、进程调度以及进程间的通信机制,掌握操作系统中进程管理的基本原理和方法,提高对操作系统的整体认识和实践能力。
二、实验环境本次实验使用的操作系统为 Windows 10,编程语言为 C 语言,开发工具为 Visual Studio 2019。
三、实验内容及步骤(一)进程的创建与终止1、编写一个 C 程序,使用系统调用创建一个子进程。
2、在父进程和子进程中分别输出各自的进程 ID 和父进程 ID。
3、子进程执行一段简单的计算任务,父进程等待子进程结束后输出结束信息。
以下是实现上述功能的 C 程序代码:```cinclude <stdioh>include <stdlibh>include <unistdh>int main(){pid_t pid;pid = fork();if (pid < 0) {printf("创建子进程失败\n");return 1;} else if (pid == 0) {printf("子进程:我的进程 ID 是%d,父进程 ID 是%d\n",getpid(), getppid());int result = 2 + 3;printf("子进程计算结果:2 + 3 =%d\n", result);exit(0);} else {printf("父进程:我的进程 ID 是%d,子进程 ID 是%d\n",getpid(), pid);wait(NULL);printf("子进程已结束\n");}return 0;}```编译并运行上述程序,可以观察到父进程和子进程的输出信息,验证了进程的创建和终止过程。
(二)进程的状态转换1、编写一个 C 程序,创建一个子进程,子进程进入睡眠状态一段时间,然后被唤醒并输出状态转换信息。
操作系统实验3进程的创建控制实验

操作系统实验3进程的创建控制实验实验三的目标是通过实现一个进程控制程序,来加深我们对进程创建和控制机制的理解,并通过实践来熟悉和掌握相关的编程技巧。
在进行实验之前,我们需要先了解进程的一些基本概念和相关知识。
首先,进程的创建是通过操作系统中的系统调用来完成的。
在Linux系统中,常用的创建进程的系统调用有fork(和exec(。
fork(系统调用可以创建一个新的进程,该进程与调用fork(的进程几乎完全相同;而exec(系统调用则在新创建的进程中执行一个新的程序。
另外,进程的控制机制主要是通过进程的状态来实现的。
进程可以处于就绪状态、运行状态和阻塞状态。
就绪状态的进程可以被调度器选择后立即运行,而阻塞状态的进程则需要等待一些条件满足后才能被唤醒并变为就绪状态。
实验三的具体内容包括:1. 编写一个程序,通过调用fork(创建多个子进程。
子进程和父进程可以并行执行,共享程序的代码和数据段。
2. 子进程通过调用exec(系统调用执行不同的程序。
可以通过调用不同的exec(函数或者传入不同的参数来执行不同的程序。
3. 子进程执行的程序可能会产生不同的结果,比如输出不同的字符串或者产生不同的返回值。
我们可以通过wait(系统调用等待子进程退出,并获取子进程的返回值。
4. 父进程可以通过调用waitpid(系统调用来选择等待一些特定的子进程,以及获取特定子进程的返回值。
通过实验三的实践,我将更加深入地了解进程的创建和控制机制。
实验三的实验结果将让我熟悉和掌握相关的编程技巧,为我今后更加熟练地编写和控制进程打下坚实的基础。
总之,实验三是一个非常有意义的实验,将帮助我更加深入地理解进程的创建和控制机制,并通过实践获得相关的编程技巧。
这将对我今后的学习和实践有很大的帮助。
操作系统实验三:进程调度

实验三进程调度1.目的和要求进程调度是处理机管理的核心内容。
本实验要求用C语言编写和调试一个简单的进程调度程序。
通过本实验可以加深理解有关进程控制块、进程队列的概念,并体会和了解优先数和时间片轮转调度算法的具体实施办法。
2.实验内容①设计进程控制块PCB表结构,分别适用于优先数调度算法和循环轮转调度算法。
②建立进程就绪队列。
对两种不同算法编制入链子程序。
③编制两种进程调度算法:1)优先数调度;2)循环轮转调度3.实验环境①PC兼容机②Windows、DOS系统、Turbo c 2.0③C语言4.实验提示①本程序用两种算法对五个进程进行调度,每个进程可有三个状态,并假设初始状态为就绪状态。
②为了便于处理,程序中的某进程运行时间以时间片为单位计算。
各进程的优先数或轮转时间数以及进程需运行的时间片数的初始值均由用户给定。
③在优先数算法中,优先数可以先取值为50-进程执行时间,进程每执行一次,优先数减3,CPU时间片数加1,进程还需要的时间片数减1。
在轮转算法中,采用固定时间片(即:每执行一次进程,该进程的执行时间片数为已执行了2个单位),这时,CPU时间片数加2,进程还需要的时间片数减2,并排列到就绪队列的尾上。
④对于遇到优先数一致的情况,采用FIFO策略解决。
5.有关实验的改进意见:在实验操作过程中,发现用户输入的数据量太大且每次用户输入的大多数数据为重复数据,因此考虑采用文件输入方式,用户只需指定特定的输入文件的文件名来输入数据。
另一方面,程序的输出量较大,可以考虑采用文件输出的方式来储存程序的运行结果。
也可以用实时的输出界面来输出程序结果。
6.实验过程(1)打开vc++,写入代码并编译,无错;(2)调试源程序,出现一个错误;(3)查找错误,进行修改,删除两个“sleep(5)”,编译并调试均无错;(4)按1是优先数算法,根据提示分别输入三个进程名和所需时间;(5)按2是轮转算法,根据提示分别输入三个进程名和所需时间;(6)按3退出;。
进程调度操作系统实验报告

进程调度操作系统实验报告一、实验目的本次实验的主要目的是深入理解操作系统中进程调度的概念和原理,通过实际编程和模拟,观察不同调度算法对系统性能的影响,并掌握进程调度的实现方法。
二、实验环境操作系统:Windows 10编程语言:C++开发工具:Visual Studio 2019三、实验原理进程调度是操作系统的核心功能之一,它负责决定哪个进程在何时获得 CPU 资源进行执行。
常见的进程调度算法有先来先服务(FCFS)、短作业优先(SJF)、时间片轮转(RR)、优先级调度等。
先来先服务算法按照进程到达的先后顺序进行调度,先到达的进程先获得 CPU 执行。
这种算法简单直观,但可能导致短作业等待时间过长。
短作业优先算法优先调度执行时间短的进程,能有效减少平均等待时间,但可能导致长作业饥饿。
时间片轮转算法将 CPU 时间划分成固定大小的时间片,每个进程轮流获得一个时间片进行执行。
如果进程在时间片内未完成,则被放回就绪队列等待下一轮调度。
优先级调度根据进程的优先级来决定调度顺序,优先级高的进程先获得 CPU 资源。
四、实验步骤1、设计进程结构体定义进程的标识号(PID)、到达时间、服务时间、剩余时间、优先级等属性。
2、实现先来先服务算法按照进程到达的先后顺序将它们放入就绪队列。
从就绪队列中取出第一个进程进行调度执行,直到其完成。
3、实现短作业优先算法计算每个进程的剩余服务时间。
将进程按照剩余服务时间从小到大排序,放入就绪队列。
从就绪队列中取出剩余服务时间最短的进程进行调度执行。
4、实现时间片轮转算法设定时间片大小。
将进程放入就绪队列,按照先来先服务的原则依次分配时间片执行。
进程在时间片内未完成的,放回就绪队列末尾。
5、实现优先级调度算法为每个进程设置优先级。
将进程按照优先级从高到低排序,放入就绪队列。
从就绪队列中取出优先级最高的进程进行调度执行。
6、计算平均周转时间和平均带权周转时间周转时间=完成时间到达时间带权周转时间=周转时间/服务时间平均周转时间=总周转时间/进程数平均带权周转时间=总带权周转时间/进程数7、输出调度结果包括每个进程的调度顺序、开始时间、结束时间、周转时间、带权周转时间等。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
操作系统实验实验三进程调度学号 1215108019 姓名李克帆班级 12电子2班华侨大学电子工程系实验目的1、理解有关进程控制块、进程队列的概念。
2、掌握进程优先权调度算法和时间片轮转调度算法的处理逻辑。
实验内容与基本要求1、设计进程控制块PCB的结构,分别适用于优先权调度算法和时间片轮转调度算法。
2、建立进程就绪队列。
3、编制两种进程调度算法:优先权调度算法和时间片轮转调度算法。
实验报告内容1、优先权调度算法和时间片轮转调度算法原理。
优先权算法:(1)当该算法用于作业调度时,系统从后备作业队列中选择若干个优先级最高的,且系统能满足资源要求的作业装入内存运行。
(2)当该算法用于进程调度时,将把处理机分配给就绪进程队列中优先级最高的进程。
时间片轮转法:系统将所有的就绪进程按先来先服务的原则,排成一个队列,每次调度时,把CPU分配给队首进程,并令其执行一个时间片.时间片的大小从几ms到几百ms.当执行的时间片用完时,由一个计时器发出时钟中断请求,调度程序便据此信号来停止该进程的执行,并将它送往就绪队列的末尾;然后,再把处理机分配给就绪队列中新的队首进程,同时也让它执行一个时间片.这样就可以保证就绪队列中的所有进程,在一给定的时间内,均能获得一时间片的处理机执行时间.2、程序流程图。
3、程序及注释。
#include <stdio.h>#include <string.h>//使用timer()函数#include <windows.h>//时间延迟#define DELAY 200 //每次运算后的停留时间//时间片#define SJP 3 //这里的时间片是固定的,这就要求每个进程的服务时间略小于4/**********全局变量声明**********/unsigned short TIME=0; //无符号,定义时间unsigned short NUM=0; //无符号,定义进程数量char TYPE='1'; //模拟类型//PCB结构体定义typedef struct PCB// struct 结构体{char name[16];char state;//[R]Run,[F]Finish,[P]Pause,[N]Newunsigned short priority; //数字越大,优先级越高,最小为1 unsigned short t_arrive; //到达时间unsigned short t_start; //开始时间unsigned short t_finish; //完成时间unsigned short t_service; //服务时间unsigned short t_run; //运行时间unsigned short t_wait; //等待时间struct PCB *next;} pcb;pcb *now=NULL, //定义now指针,一开始不赋值。
指向现在运行的pcb*head=NULL; //pcb链头部指针/**********函数声明**********/void fcfs(); //先到先服务void sjf(); //短作业优先void gyxb(); //高优先比void sjplz(); //时间片轮转void init(); //初始化,完成pcb录入pcb *sort(pcb*); //对init()录入的pcb按到达时间排序void timer(); //定时器,每一个延迟自我调用一次void result(); //打印结果//先到先服务算法void fcfs(){if(now->t_arrive>TIME) //判断有无进程到达{printf("[时间:%d]\t无进程运行\n",TIME);return;}if(now->state=='N') //判断state的状态{now->state='R'; //如果是新的程序,将state改为Rnow->t_start=TIME;printf("[时间:%d]\t进程:%s 首次运行\n",TIME,now->name);//显示该程序第一次运行}else if(now->state=='R')//else if语句中嵌套两个if语句,用来判断进程处在运行阶段还是完成阶段{(now->t_run)++;//now取t_run中的地址,再取内容if(now->t_run>=now->t_service)//判断任务是否完成,标准时运行时间大于服务时间{now->state='F';//如果完成,则state的状态由Run改为Finallynow->t_finish=TIME;printf("[时间:%d]\t进程:%s 任务完成\n",TIME,now->name);//任务完成,跳出ifnow=now->next;if(now!=NULL) fcfs();//判断是否还有未完成的程序}else printf("[时间:%d]\t进程:%s 正在运行,已运行时间:%d\n",TIME,now->name,now->t_run);//任务未完成,返回外层语句继续循环执行}}//短作业优先算法void sjf(){pcb *p=head,*p_min=NULL;//创建p和p_min两个指针unsigned short t_min=9999;//从现在时间以前并且未结束的进程中,选出服务时间最小的进程while(p!=NULL && p->t_arrive<=TIME){if(p->state=='F')//判断程序是否结束{p=p->next;continue;}if((p->t_service-p->t_run)<t_min)//这个if语句用来筛选最短时间的程序{t_min=p->t_service;p_min=p;}p=p->next;}if(p_min==NULL) //如果为空,判断全部进程是否都已完成{char k='Y';p=head;while(p!=NULL){if(p->state!='F')//state状态为F时也被视为无程序在运行k='N';p=p->next;//p前往下一个程序进行扫描}if(k=='Y')now=NULL;else printf("[时间:%d]\t无进程运行\n",TIME);return;}if(p_min!=now)//如果选出的进程和之前的不同{if(now->state=='R')//暂停现在正在运行的程序,将state的状态改为P{now->state='P';printf("[时间:%d]\t进程:%s 暂停运行\n",TIME,now->name);}}if(p_min==NULL) now=head;else now=p_min;if(now->state=='N')//将新进程的状态改为正在运行的进程,并标显示进程正在运行{now->state='R';now->t_start=TIME;printf("[时间:%d]\t进程:%s 首次运行\n",TIME,now->name);}else{if(now->state=='P')//若进程被暂停,则将进程开启{now->state='R';printf("[时间:%d]\t进程:%s 继续运行\n",TIME,now->name);}(now->t_run)++;if(now->t_run>=now->t_service)//把服务时间赋予运行时间{now->state='F';now->t_finish=TIME;printf("[时间:%d]\t进程:%s 任务完成\n",TIME,now->name);gyxb();}else printf("[时间:%d]\t进程:%s 正在运行,已运行时间:%d\n",TIME,now->name,now->t_run);}}//高优先比算法void gyxb(){pcb *p=head,*p_min=NULL;unsigned short t_min=0;//从现在时间以前并且未结束的进程中,选出服务时间最小的进程while(p!=NULL && p->t_arrive<=TIME){if(p->state=='F')//检查运行完成的程序,标准时state的状态为Finish{p=p->next;continue;}//动态优先比if(p->state=='P')//设置动态优先比{p->t_wait++;p->priority+=p->t_wait/p->t_service+1;/////////////////////////////////////////////////////////// //////////////}if(p->priority>t_min)//如果现有的程序优先级大于先前程序的优先级,则进行替换。
{t_min=p->priority;p_min=p;}p=p->next;}//如果为空,判断全部进程是否都已完成if(p_min==NULL){char k='Y';p=head;while(p!=NULL){if(p->state!='F')//state状态为F时也被视为无程序在运行k='N';p=p->next;//运用p指针逐个扫描}if(k=='Y')now=NULL;else printf("[时间:%d]\t无进程运行\n",TIME);return;}//如果选出的进程和之前的不同if(p_min!=now){if(now->state=='R')//进程不同则暂停现在运行的程序{now->state='P';printf("[时间:%d]\t进程:%s 暂停运行\n",TIME,now->name);}}if(p_min==NULL) now=head;else now=p_min;if(now->state=='N'){now->state='R';now->t_start=TIME;printf("[时间:%d]\t进程:%s 首次运行\n",TIME,now->name);}else{if(now->state=='P'){now->state='R';now->t_wait=0;printf("[时间:%d]\t进程:%s 继续运行\n",TIME,now->name);}(now->t_run)++;if(now->t_run>=now->t_service){now->state='F';now->t_finish=TIME;printf("[时间:%d]\t进程:%s 任务完成\n",TIME,now->name);sjf();}else printf("[时间:%d]\t进程:%s 正在运行,已运行时间:%d\n",TIME,now->name,now->t_run);}}//时间片轮转算法void sjplz(){pcb* p=head,*q=now;//p,q分别取head和now的地址//每个时间片结束时的处理if(TIME%SJP==0 && TIME/SJP>0)//如果时间片结束时程序还没有完成则执行下面的语句{char k='Y';while(p!=NULL){if(p->state!='F'){k='N';break;}p=p->next;}if(k=='Y'){now=NULL;return;}if(p!=NULL){while(1){if (q->next!=NULL){if((q->next)->state=='F'){q=q->next;continue;}else{now=q->next;break;}}else{q=head;if(q->state=='F') continue;else{now=head;break;}}}}else{p=head;while(p->next!=NULL) p=p->next;now=p;}}if(now->t_arrive>TIME){printf("[时间:%d]\t无进程运行\n",TIME);return;}if(now->state=='N'){now->state='R';now->t_start=TIME;printf("[时间:%d]\t进程:%s 首次运行\n",TIME,now->name);}else if(now->state=='R'){(now->t_run)++;if(now->t_run>=now->t_service){now->state='F';now->t_finish=TIME;printf("[时间:%d]\t进程:%s 任务完成\n",TIME,now->name);if(now!=NULL) fcfs();}else printf("[时间:%d]\t进程:%s 正在运行,已运行时间:%d\n",TIME,now->name,now->t_run);}else if(now->state=='F')printf("[时间:%d]\t无进程运行\n",TIME);}void result()//结果的显示{pcb *p=head; //输出语句printf("\n=============运行结果===========\n\n");printf("名称优先级到达时间开始时间完成时间服务时间周转时间带权周转时间\n");while(p!=NULL){printf(" %s\t%d\t %d\t %d\t %d\t %d\t %d\t %.2f\n",p->name,p->priority,p->t_ar rive,p->t_start,p->t_finish,p->t_service,p->t_finish-p->t_arrive,1.0*(p->t_finish-p->t_arrive)/p->t_service);p=p->next;}getchar();}void timer()//用timer来选取即将用的函数{if(TYPE=='1') fcfs();else if(TYPE=='2') sjf();else if(TYPE=='3') gyxb();else if(TYPE=='4') sjplz();if(now==NULL) return;TIME++;Sleep(DELAY);timer();}void init(){pcb *p,*q;unsigned short i;printf("\n=====================实验3NEMO===========================\n\n");printf(" ***输入服务类型*** \n");printf("\n 1:先来先服务\n");printf("\n 2:短作业优先\n");printf("\n 3:高优先权优先\n");printf("\n 4:时间片轮转\n");scanf("%c",&TYPE);printf("输入进程数目:\n");scanf("%d",&NUM);for(i=0; i<NUM; i++)//for循环用来重复输入已确定的进程数目{p=(pcb *)malloc(sizeof(pcb));printf("[第%d个] 依次输入:名称优先权到达时间服务时间\n",i+1);scanf("%s\t%d\t%d\t %d",&p->name,&p->priority,&p->t_arrive,&p->t_service);if(head==NULL){head=p;q=p;}q->next=p;//利用确定的p,q指针进行初始化p->t_start=0;p->t_finish=0;p->t_run=0;p->t_wait=0;p->next=NULL;p->state='N';q=p;}getchar();}//按到达时间冒泡排序pcb* sort_pcb(pcb *h_head){pcb *p,*p1,*p2,*p3;//设置p,p1,p2,p3,p4四个指针pcb h, t;if (h_head == NULL) return NULL;h.next=h_head;p=&h; //p作为指针,存储了h的地址while (p->next!=NULL){p=p->next;}p=p->next=&t;while (p!=h.next)//{p3=&h;p1=p3->next;p2=p1->next;while (p2!=p){if ((p1->t_arrive)>(p2->t_arrive))//按到达的时间比较{p1->next=p2->next;p2->next=p1;p3->next=p2;p3=p2;p2=p1->next;}else{p3=p1;p1=p2;p2=p2->next;}}p=p1;}while (p->next!=&t){p=p->next;}p->next=NULL;return h.next;}void main(){init();system("CLS");head=sort_pcb(head);now=head;printf("进程正在运行……\n");timer();result();return;}4、运行结果以及结论。