一. 实验目的
(1)加深对进程概念的理解,明确进程和程序的区别
(2)深入理解系统如何组织进程
(3)理解常用进程调度算法的具体实现
二. 实验内容
(1)编写C程序模拟实现单处理机系统中的进程调度算法,实现对多个进程的调度模拟,要求采用常见进程调度算法(如先来先服务、时间片轮转和优先级调度等算法)进行模拟调度。
三. 实验步骤
(1)编写C程序:
#include <stdio.h> #include <stdlib.h> #define getpch(type) (type*)malloc(sizeof(type)) struct pcb { char name[10]; char state; int nice; int ntime; int rtime; struct pcb *link ; }*ready=NULL,*p; typedef struct pcb PCB; void sort() { PCB *first,*second; int insert=0; if((ready==NULL)||(p->nice > ready->nice)) { p->link=ready; ready=p; } else { first=ready; second=first->link; while(second !=NULL) { if(p->nice>second->nice) { p->link=second; first->link=p; second=NULL; insert=1; } else { first=first->link; second=second->link; } } if(insert==0) first->link=p; } } void input() { int i,num; printf("\n请输入被调度的进程数目:"); scanf("%d",&num) ; for(i=0; i<num; i++) { printf("\n进程号No.%d : ",i); p=getpch(PCB); printf("\n输入进程名:"); scanf("%s",p->name) ; printf("输入进程优先级:"); scanf("%d",&p->nice); printf("输入进程运行时间:"); scanf("%d",&p->ntime); printf("\n"); p->rtime=0; p->state= 'W'; p->link=NULL; sort(); } } int space() { int l=0; PCB *pr=ready; while(pr !=NULL) { l++; pr=pr->link; } return (l); } void disp(PCB *pr) { printf("\n qname lt state lt nice ltndtime \truntime \n"); printf("%slt",pr->name); printf("%c\t",pr->state); printf("%d\t",pr->nice); printf("%d\t",pr->ntime); printf("%d\t",pr->rtime); printf("\n"); } void check() { PCB *pr; printf("\n****当前正在运行的进程是:%s",p->name); disp(p); pr=ready; if(pr!=NULL) printf( "\n****当前就绪队列为:"); else printf( "\n****当前就绪队列为空\n"); while(pr !=NULL) { disp(pr); pr=pr->link; } } void destroy() { printf("进程[%s]己完成。\n",p->name); free(p); } void running() { (p->rtime)++; if(p->rtime==p->ntime) destroy(); else { (p->nice)--; p->state= 'W'; sort(); } } int main( ) { int len,h=0; char ch; input(); len=space(); while( len!=0 && ready !=NULL) { h++; printf( "in The execute number:%d\n",h); p=ready ; ready=p->link; p->link=NULL; p->state='R'; check(); running(); printf( "\n按任意键继续.......\n"); ch=getchar(); } printf( "\n\n所有进程己经运行完成!\n"); ch=getchar(); return 0; }
这段代码是一个模拟操作系统进程调度的程序。下面对代码进行详细分析:
- 定义了一个进程控制块(PCB)的结构体,包含进程名(name)、状态(state)、优先级(nice)、需要运行时间(ntime)、已运行时间(rtime)和链接指针(link)。
- 定义了一个全局变量ready,用于存储就绪队列中的所有进程。还定义了一个指针p,用于指向当前正在执行的进程。
- 定义了一个宏函数getpch(),用于动态分配内存空间来创建一个进程控制块。
- 定义了一个函数sort(),用于将新创建的进程按照优先级插入到就绪队列中。
- 定义了一个函数input(),用于从用户输入中获取要调度的进程的信息,并将其插入到就绪队列中。
- 定义了一个函数space(),用于计算就绪队列中的进程数目。
- 定义了一个函数disp(),用于显示某个进程的信息。
- 定义了一个函数check(),用于显示当前正在运行的进程和就绪队列中的进程信息。
- 定义了一个函数destroy(),表示进程已完成,释放其占用的内存空间。
- 定义了一个函数running(),表示当前正在运行的进程进行运行,如果运行时间等于需要运行时间,则调用destroy()函数,否则将优先级减1,并将进程插入到就绪队列中。
- 主函数main()中,首先调用input()函数获取要调度的进程信息。然后进入一个循环,循环条件为就绪队列不为空且进程数目不为0。在循环中,将就绪队列的第一个进程取出来赋给p,并从就绪队列中移除。然后调用running()函数进行运行,最后输出当前正在运行的进程和就绪队列的信息。循环结束后,输出所有进程已经运行完成的信息。
总结:这段代码实现了一个简单的进程调度模拟,根据进程的优先级进行调度,并按照时间片轮转的方式进行运行。
四. 实验结果
五. 实验总结
处理机调度是操作系统中的一个关键部分,它负责决定哪个进程将获得处理器运行的机会。处理机调度的目标是实现公平性、高效性和响应时间的优化。
处理机调度的主要任务是根据一定的算法选择一个进程从就绪队列中调出,然后将处理器分配给它执行。调度算法的选择对系统的性能和效率有重要影响。
常见的调度算法有以下几种:
- 先来先服务(FCFS)调度算法:按照进程的到达顺序进行调度,先到达的进程先执行。
- 短作业优先(SJF)调度算法:根据进程的执行时间进行调度,执行时间越短的进程会被优先调度。
- 优先级调度算法:根据进程的优先级进行调度,优先级高的进程会被优先调度。可以根据进程的重要性、紧急程度或其他指标来确定优先级。
- 时间片轮转调度算法:每个进程被分配一个固定的时间片,在时间片用完之前,如果进程没有执行完毕,会被挂起,然后选择下一个进程运行。
- 多级反馈队列调度算法:将就绪队列按照优先级划分为多个队列,每个队列都有一个时间片,进程首先被放入优先级最高的队列,如果运行时间超过时间片,则进程会被移到下一个优先级队列。
- 最短剩余时间优先(SRTF)调度算法:根据进程剩余需要执行的时间进行调度,剩余执行时间最短的进程会被优先调度。
处理机调度算法的选择要根据系统的需求和性能特点进行权衡。不同的调度算法在不同的场景下会有不同的效果。例如,短作业优先算法适合执行时间短的任务,而多级反馈队列算法适合在系统中有不同优先级的进程。
处理机调度对于操作系统的性能和响应时间至关重要。一个高效的调度算法可以提高系统的利用率和响应速度,同时也能够保证公平性和资源的合理分配。因此,处理机调度是操作系统中一个非常重要的功能模块。