实习一 处理器调度
一、实习内容
选择一个调度算法,实现处理器调度。
二、实习目的
本实习模拟在单处理器环境下的处理器调度,加深了解处理器调度的工作。
三、实习题目
本实习有两题,可任选一题。
第一题:设计一个按优先数调度算法实现处理器调度的程序。
[提示]:
(1)假定系统有5个进程,每个进程用一个PCB来代表。PCB的结构为:
·进程名——如P1~P5。
·指针——按优先数的大小把5个进程连成队列,用指针指出下一个进程PCB的首地址。
·要求运行时间——假设进程需要运行的单位时间数。
·优先数——赋予进程的优先数,调度时总是选取优先数大的进程先执行。
·状态——假设两种状态:就绪和结束,用R表示就绪,用E表示结束。初始状态都为就绪状态。
(2) 开始运行之前,为每个进程确定它的“优先数”和“要求运行时间”。通过键盘输入这些参数。
(3) 处理器总是选择队首进程运行。采用动态改变优先数的办法,进程每运行1次,优先数减1,要求运行时间减1。 (4) 进程运行一次后,若要求运行时间不等于0,则将它加入就绪队列,否则,将状态改为“结束”,退出就绪队列。 (5) 若就绪队列为空,结束,否则转到(3)重复。 要求能接受键盘输入的进程优先数及要求运行时间,能显示每次进程调度的情况,如哪个进程在运行,哪些进程就绪,就绪进程的排列情况。
代码:#include \#include
struct PCB //定义一个进程结点数据域 {
char name[3]; //进程名 int run_time; //运行时间 int level; //优先数 char state; //运行状态
struct PCB *next; //指向下一个结点的指针 };
struct PCB *creat() //创建一个函数,用于返回一个链表 {
int i = 1;
int time, slevel; //用来存储用户输入
struct PCB *head, *tail, *temp, *previous; //申明指针
char PCB_name[5][3] = {\//初始化进程名数组
temp = (struct PCB *)malloc(sizeof(struct PCB)); //给temp指针分配内存
printf(\请输入第1个结点的优先数: \ scanf(\
printf(\请输入第1个结点的运行时间: \ scanf(\
temp->level = slevel; //将输入的优先数赋值给temp结点的优先数
strcpy(temp->name, PCB_name[0]); //将PCB_name[0]复制给temp结点
temp->next = NULL; //temp结点的下一个为空 temp->run_time = time; //获取输入的运行时间 temp->state = 'R'; //运行状态为就绪
head = tail = temp; //指向当前第一个结点
while (i != 5) //i的初值为1,这里不等于5,意思就是继续添加四个结点 {
temp = (struct PCB *)malloc(sizeof(struct PCB)); //分配一段新的内存给temp
printf(\请输入第%d个结点的优先数: \ scanf(\
printf(\请输入第%d个结点的运行时间: \ scanf(\
temp->level = slevel; //同上 strcpy(temp->name, PCB_name[i]); temp->run_time = time; temp->state = 'R';
if (temp->level > head->level) //比较当前定义的结点的优先数与head的优先数,同时head指向的结点的优先数是最大的 {
temp->next = head; //如果前定义的结点的优先数与head的优先数大,则head指向当前定义的结点 head = temp; } else
{
previous = head;
while (previous->next != NULL) //如果比优先数最大的结点小,则继续与后面的节点进行比较,知道找到一个合适的位置,即为比前面结点的优先数大,比后面的小
{
if ((temp->level <= previous->level) && (temp->level >= (previous->next)->level)) {
temp->next = previous->next; //交换两个结点的位置
previous->next = temp; break; } else {
previous = previous->next; //实现往后移 } }
if (previous->next == NULL) //如果没有找到比当前结点小的,则将当前结点放在最后面 {
tail->next = temp; temp->next = NULL; tail = temp; } } i++; }
return (head); //返回一个链表的头结点 }
void display(struct PCB *p) //用于输出当前链表中各结点的状态 {
while (p != NULL) {
printf(\ printf(\ printf(\ printf(\ printf(\
p = p->next; //实现往后移 } }
void main( void ) {
struct PCB *head, *tail, *p;
head = creat(); //调用函数creat,head指向头结点 p = head; tail = p;
printf(\初始进程的情况: \\n\
display(p); //显示当前结点的情况
while(head->next != NULL) //判断当前链表中的结点是否不止一个 {
struct PCB *q = head; struct PCB *previous;
tail = head;
while (tail->next != NULL) //将tail指针指向尾结点 {
tail = tail->next; }
printf(\最新进程调度的情况: \\n\
printf(\ //输出最近调用的进程名
display(q); //显示当前调用情况
head->level--; //优先数减1 head->run_time--; //运行时间减1
if(head->run_time <= 0) //如果优先数最大的结点的运行时间小于或者等于0,则将该节点从链表中移除 {
head->state = 'E'; head = head->next; } else
操作系统实验及源代码



