操作系统实验三(进程调度之优先数与时间片)

. 实验目的

  理解进程运行的并发性

    理解进程各种状态及其之间的转换 

   理解进程管理中PCB的结构

         掌握优先数进程调度算法

. 实验内容

    VC编写实现进程调度算法模拟进程调度的实现过程。调度算法采用的是动态优先数与时间片相结合的算法。要求如下

  • 进程相关信息如进程标识符及进程所需时间都放入PCB中;
  • 设计运行、完成和就绪三个进程队列;
  • 就绪队列按优先数从小到大排列,每次选择优先数最大的就绪进程运行。初始优先数定为用一个较大的数(如30)减去进程运行时间,随着进程的运行对优先数进行调整;
  • 进程每执行一次,优先数减一个固定值(如3),CPU时间加1,进程所需时间减1.如果进程所需时间变为0,说明进程运行完毕,将其状态置为"F",将其PCB插入到完成队列中,此时若就绪队列不空,则将就绪队列的第一个PCB变为运行状态。 如果进程未完成,则将其优先数和就绪队列中第一个PCB优先数比较,如果小,则将其变为就绪态,插入就绪队列中适当位置,同时将就绪队列中第一个PCB变为运行态。重复上述过程直到就绪队列为空,所有进程成为完成状态。

    相关数据结构:

          typedef struct node{ 

                 char name[10];       //进程标识符

                 int prio;        //进程优先级

                 int cput;       //进程占用的CPU时间

                 int needt;            //进程离完成还需要的CPU时间

                char state;         //进程状态 struct node *next;

        }PCB;

 

三、实验代码

     参考实验二中的代码自行完成该算法代码。

要求:

   编写算法实现的流程图

   编程实现题目要求的功能

   测试多组数据的实验结果

#include <iostream>
#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <cstring>
#include <bits/stdc++.h> 
using namespace std;
//定义动态申请空间的函数 
#define getpch(type) (type*)malloc(sizeof(type))
typedef struct node {
    int ID;//进程的标识符 
    int prio;//进程的优先级 
    int cput;//进程占用的CPU时间 
    int ncput;//进程离完成还需要的CPU时间 
    char state;//进程的状态 R运行,W等待,在run中使用F-T。 
    struct node *next;
}PCB;
PCB *ready, *run, *finish;//准备,运行,完成。 
void InitProcess();//进程的初始化设置
void insertByDesc(PCB *p);//插入节点,按照从大到小排序(优先级高的先运行) 
void printreadyinfo();//输出就绪队列的信息
void processrunning();//进程开始运行 
void JoinCPU();//从进程中选取一个进程进入CPU开始运行
void showrun(PCB *p);//显示正在运行的进程(显示过程) 
void showfinish(PCB *p);//显示完成的信息 
void setfinish(PCB *p);////进程完成,设置为完成
//主函数 
int main() {
    run = getpch(PCB);//申请节点空间 
    finish =getpch(PCB);
    ready = getpch(PCB);
    ready->next = NULL;
    run->next = NULL;
    finish->next = NULL;
    InitProcess();//初始化进程 
    processrunning();
    return 0;
}
void showrun(PCB *p) {
    printf("进程运行的信息:\n");
    cout<<"ID"<<"   "<<"Prio"<<"   "<<"cput"<<"   "<<"ncput"<<"   "<<"state"<<endl;
    printf("%-4d %-7d %-7d %-7d %-7c\n", p->ID, p->prio, p->cput, p->ncput, p->state);
}
void showfinish(PCB *p) {
    printf("完成的进程信息:\n");
    cout<<"ID"<<"   "<<"Prio"<<"   "<<"cput"<<"   "<<"ncput"<<"   "<<"state"<<endl;
    printf("%-4d %-7d %-7d %-7d %-7c\n", p->ID, p->prio, p->cput, p->ncput, p->state);
}
//进程完成,设置为完成 
void setfinish(PCB *p) {
    PCB *r;
    if (p->ncput == 0) {//如果运行所需时间为0,放入finish
        r = finish;
        while (r->next != NULL) {
            r = r->next;
        }
        p->state = 'F';//将当前进程置为完成状态
        p->next = r->next;
        r->next = p;
        showfinish(p);//输出完成的信息 
    }
}
//从进程中选取一个进程进入CPU开始运行 
void JoinCPU() {
    if (ready->next != NULL) {//如果就绪队列不为空,第一个PCB置运行
        run->next = ready->next;//开始运行 
        ready->next = ready->next->next;//第一个从就绪队列删除
        run->next->state = 'R';//运行的进程状态改为R 
        run->next->prio -= 3;//每进入CPU一次优先级-3 
        run->next->cput += 1;//CPU占用的时间+1 
        run->next->ncput -= 1;//一共还需要的时间-1 
    }
}
void processrunning() {
    JoinCPU();
    setfinish(run->next);//时间为零置finish
    if (run->next->state != 'F')
        showrun(run->next);
    while (1) {
        if (ready->next != NULL && run->next->prio < ready->next->prio) { //小于第一个PCB优先数就将其插入就绪并调用下一个进程
            if (run->next->state != 'F')//如果进程已完成就不用插入就绪
                insertByDesc(run->next);//重新进行排序 
            JoinCPU();
            setfinish(run->next);
            if (run->next->state != 'F')
                showrun(run->next);
 
        }
        else
        {
            run->next->prio -= 3;
            run->next->cput += 1;
            run->next->ncput -= 1;
            setfinish(run->next);
            if (run->next->state != 'F')
                showrun(run->next);
            if (ready->next == NULL) {
                break;
            }
 
        }
    }
}
//输出就绪队列的信息 
void printreadyinfo() {
    PCB *p;
    p = ready->next;
    cout<<"就绪进程的信息(ready info)"<<endl;
    cout<<"ID"<<"   "<<"Prio"<<"   "<<"cput"<<"   "<<"ncput"<<"   "<<"state"<<endl;
    while (p != NULL) {
        printf("%-4d %-7d %-7d %-7d %-7c\n", p->ID, p->prio, p->cput, p->ncput, p->state);
        p = p->next;
    }
}
//插入节点,按照从大到小排序(优先级高的先运行) 
void insertByDesc(PCB *p){
    PCB *tmp;
    tmp = ready;
    while (tmp->next != NULL && tmp->next->prio >= p->prio) {//从大到小排序
        tmp = tmp->next;
    }
    //第一个节点 
    p->next = tmp->next;
    tmp->next = p;
}
//进程状态的初始化: 
void InitProcess() {
    PCB *p;
    int n;
    printf("情输入进程的个数:");
    cin>>n;//输入了进程的个数; 
    cout<<"请输入进程的标识符和程占用的CPU时间"<<endl; 
    for (int i = 1; i <= n; i++) {
        p = getpch(PCB);
        int id, pri, needt;//设置变量,进程的标识,优先级,占用CPU的时间。 
        cin>>id>>needt;
        p->ID = id;
        p->prio = 30;//优先级初始状态为30 
        p->cput = 0;//初始化时还未占用CPU 
        p->ncput = needt;//一共需要的CPU时间 
        p->state = 'w';//状态等待。 
        insertByDesc(p);
    }
    printreadyinfo(); 
}

 

  

 

 

 

 

 

 

 

 

 

 

 

 

 

  

posted @ 2020-04-22 19:55  薄眠抛却陈年事。  阅读(1959)  评论(0编辑  收藏  举报