模拟计算机中进程调度

2019-02-19  本文已影响0人  吃茶的武士

【实验目的】

在多道程序或者任务系统中,系统同时处于就绪状态的进程有若干个。也就是说能运行的进程数远远大于处理机个数,为了使系统中的各进程能有条不紊的运行,必须选择某种调度策略,以选择一进程占用处理机。这样便要求我们来设计模拟进程调度的算法,来模拟实现计算机中的进程安排。此次实验模拟三种,先来先服务,优先级调度,时间片轮转。

【实验原理】

[if !supportLists]1. [endif]首先是操作系统中

<1>.先来先服务调度,就是哪一个进程先到达的,它的优先级就是最高,优点是实现简单,只需要根据arrivetime实现一个排序就行,缺点也是多多,不赘述了;按照优先级调度的算法,这个算法里面,我们给进程安排了一个重要程度yxj,按照这个排好队,然后每执行一次优先级就下降,这个实现就比较困难了,体现在新的进程到来的插入,以及后面判断就绪;时间片轮转是一种比较好的算法,每个进程都可以排队使用处理机,一开始的就绪队列就是按照先来先服务排序的。

2.在实现中,用到了c语言中的指针数组知识,数据结构中链表的知识,尤其是链表的操作(插入,改变顺序等等)。体现了学科间的紧密结合与相互服务吧

【小结或讨论】

这次的实验感觉很有难度,实验指导书上要求的数据结构设计的链表指针已经是大一知识了,这也是自己很少锻炼的原因。尤其是数据结构,本身难度就很大,需要再好好的看一遍,弄清楚排序,插入,指向等诸多问题。不过操作系统中的概念得到了理解记忆,尤其是第二个优先级调度和第三个时间片,在处理进程后,优先级如何变化?这个进程要被插入到哪里?这个时间片用完进程这么安排很多问题。

看书,看数据结构以及操作系统课本,想清楚进程的去向等基本问题,多练习。

代码:

轮转调度:

#define N 20

#include<stdio.h>

#include<conio.h>

#include<stdlib.h>

#include<string.h>

struct pcb

{

char pname[N];//进程名

int runtime;//估计运行时间

int arrivetime;//到达时间

char state;//进程状态

struct pcb *next;//后继指针

struct pcb *prev;//前驱指针

};

int num=5;

pcb *p;

pcb *n;

pcb *time;

pcb *head;

pcb *tail;

pcb *head1;

int sum;

int i,j;

char R='r',C='c';

int current=0;

int inputprocess();//建立进程函数

//int readyprocess();//建立就绪队列函数

int readydata();//判断进程是否就绪函数

//int runprocess();//运行进程函数

int inputprocess(){                    //按到达时间插入

for(i=0;i<num;i++){

pcb *p1=new pcb;

printf("输入进程的信息:\n");

printf("第%d个进程的名字:",i+1);

scanf("%s",p1->pname);

printf("第%d个进程的运行时间:",i+1);

scanf("%d",&(p1->runtime));

printf("第%d个进程的到达时间:",i+1);

scanf("%d",&(p1->arrivetime));

p1->state=R;

if(i==0){

p=p1;

p->next=NULL;

head=p;

}

else{

p=head;

while((p!=NULL)&&(p->arrivetime<p1->arrivetime))

p=p->next;

    if(p==NULL){

    p=head;

    while(p->next!=NULL)

    p=p->next;

    p->next=p1;

    p1->prev=p;

    p1->next=NULL;

}

else{

if(p==head){

head=p1;

p1->next=p;

p->prev=p1;

}

else{

p1->prev=p->prev;

p->prev->next=p1;

p1->next=p;

p1=p->prev;

}

}

}

}

p=head;

while(p->next!=NULL)

p=p->next;

tail=p;

return 1;

}

void fuz(pcb *p1,pcb *p2){            //将p2中的值付给p1

p1->arrivetime=p2->arrivetime;

strcpy(p1->pname,p2->pname);

p1->runtime=p2->runtime;

p1->state=p2->state;

}

int readydata(){

for(p=head;p!=NULL;p=p->next)

{

if(p==head)

  sum=p->arrivetime+p->runtime;

else{

if(sum<p->arrivetime)

  sum=p->arrivetime+p->runtime;

else

  sum=sum+p->runtime;

}

}

current=head->arrivetime;

p=head;

while(current<=sum){

printf("当前时间为:%d\n",current);

while((p!=NULL)&&(current==p->arrivetime)){

pcb *m=new pcb;

fuz(m,p);

if(p==head){

head1=m;

time=m;

time->next=NULL;

}

else{

for(time=head1;time->next!=NULL;time=time->next);

time->next=m;

m->prev=time;

m->next=NULL;

}

p=p->next;

}

    head1->runtime--;

    if(head1->next==NULL)

        n=head1;

    else

        n=head1->next;

    if(head1->runtime==0){

    printf("进程%s已结束.\n",head1->pname);

    head1->next->prev=NULL;

        head1->next=NULL;

}

else{

for(time=head1;time->next!=NULL;time=time->next);

if(time!=head1){

time->next=head1;

head1->prev=time;

head1->next->prev=NULL;

        head1->next=NULL;

}

}

head1=n;

printf("就绪队列中的进程为:");

for(time=head1;time!=NULL;time=time->next)

  printf("%s",time->pname);

printf("\n");

    current++;

}

    return 1;

}

int main(){

inputprocess();

printf("进程名      到达时间        运行时间\n");

for(p=head;p!=NULL;p=p->next)

printf("%s            %d            %d\n",p->pname,p->arrivetime,p->runtime);

readydata();

return 1;

}


FCFS:

//FCFS,先来先服务

#include <iostream>

#include "string"

#include "algorithm"

using namespace std;

//进程类

class process{

public:

    string name;//进程名

    double arrive; //进程到达时刻

    double service;//进程服务时间

    void print(){

        cout<<name<<"\t\t";

        cout<<arrive<<"\t\t";

        cout<<service<<"\t\t";

    }

};

//比较两个进程到达时间的先后

bool compare(process a,process b){

    return a.arrive<b.arrive;

}

int main(int argc, const char * argv[]) {

    int n;                  //进程个数

    process pro[10];        //进程数组

    cout<<"请输入c进程个数: ";

    cin>>n;

    cout<<"请分别输入这些进程的:\n进程名\t到达时刻\t服务时间\n";

    for(int i=0;i<n;i++){

        cin>>pro[i].name;

        cin>>pro[i].arrive;

        cin>>pro[i].service;

    }

    //"algorithm"文件里的sort函数

    sort(pro,pro+n,compare);    //s进程数组按到达时间从小到大排序

    cout<<"进程名\t到达时刻\t服务时间\t开始执行时刻\t完成时刻\t周转时间\t带权周转时间\n";

    double begin=pro[0].arrive;    //初始到达时间

    for(int i=0;i<n;i++){

        double end=begin+pro[i].service;  //完成时刻

        double zz=end-pro[i].arrive;      //周转时间

        double dqzz=zz/pro[i].service;

        pro[i].print();

        cout<<begin<<"\t\t\t";

        cout<<end<<"\t\t";

        cout<<zz<<"\t\t";

        cout<<dqzz<<"\n";

        begin=end>pro[i+1].arrive?end:pro[i+1].arrive;

    }

    cin>>n;

    return 0;

}


SJF

//SJF

#include <iostream>

#include "string"

#include "algorithm"

using namespace std;

//进程类

class process{

public:

    string name;    //进程名

    double arrive;  //进程到达时刻

    double service; //进程服务时间

    void print(){

        cout<<name<<"\t\t";

        cout<<arrive<<"\t\t";

        cout<<service<<"\t\t";

    }

};

//比较两个进程到达时间的先后

bool compare(process a,process b){

    return a.arrive<b.arrive;

}

//比较两个进程服务时间

bool compare2(process a,process b){

    return a.service<b.service;

}

int main(int argc, const char * argv[]) {

    int n;                  //进程个数

    process pro[10];        //进程数组

    cout<<"请输入c进程个数: ";

    cin>>n;

    cout<<"请分别输入这些进程的:\n进程名\t到达时刻\t服务时间\n";

    for(int i=0;i<n;i++){

        cin>>pro[i].name;

        cin>>pro[i].arrive;

        cin>>pro[i].service;

    }

    //"algorithm"文件里的sort函数

    sort(pro,pro+n,compare);    //s进程数组按到达时间从小到大排序

    cout<<"进程名\t到达时刻\t服务时间\t开始执行时刻\t完成时刻\t周转时间\t带权周转时间\n";

    double begin=pro[0].arrive;        //初始到达时间

    for(int i=0;i<n;i++){

        double end=begin+pro[i].service;//完成时刻

        double zz=end-pro[i].arrive;    //周转时间

        double dqzz=zz/pro[i].service;  //带权周转时间

        pro[i].print();

        cout<<begin<<"\t\t\t";

        cout<<end<<"\t\t";

        cout<<zz<<"\t\t";

        cout<<dqzz<<"\n";

        int nn=0;

        for(int j=1;j<n-i;j++){

            if(end>=pro[i+j].arrive)

                nn++;

        }

        if(nn>1)

            sort(pro+i+1,pro+i+1+nn,compare2);

        begin=end>pro[i+1].arrive?end:pro[i+1].arrive;

    }

    cin>>n;

    return 0;

}


优先级调度算法

#include<stdio.h>

#include<conio.h>

#include<stdlib.h>

struct pcb

{

char pname[5];//进程名

int yxs;//优先数

int runtime;//估计运行时间

char state;//进程状态

struct pcb *next;//后继指针

struct pcb *prev;//前驱指针

};

//int num=5;//进程的个数

pcb *p; //定位到当前处理位置的指针

pcb *head; //头指针指向头节点

int sum=0;

int i,j,m;

char R='r',C='c';//进程的状态

//unsigned long current=0;

int inputprocess();//建立进程函数

int readydata();

int inputprocess(){

for(i=0;i<5;i++){

pcb *p1=new pcb;

printf("输入进程的信息:\n");

printf("第%d个进程的名字:",i+1);

scanf("%s",p1->pname);

printf("第%d个进程的运行时间:",i+1);

scanf("%d",&(p1->runtime));

printf("第%d个进程的优先数:",i+1);

scanf("%d",&(p1->yxs));

p1->state=R;

if(i==0)

{ //如果是插入第一个,直接插入即可

      p=p1;

      p->next=NULL;

      head=p;

}

else{//如果不是第一个,那么需要按照优先数从小到大进行排序插入

p=head;

while((p!=NULL)&&(p->yxs<p1->yxs))

p=p->next;

    if(p==NULL){ //p==NULL

    p=head;//链表中优先级都比现在要插入的高

    while(p->next!=NULL)

    p=p->next;

    p->next=p1;

    p1->prev=p;

    p1->next=NULL; //将p1插入到链表的尾端

  }

else{//直接插入

if(p==head){ //p==head说明插入的位置为链表的表头,p1给head

head=p1;

p1->next=p;

p->prev=p1;

}

else{  //直接插入,p!=head情况,把p1插入到p前面

p1->prev=p->prev;

p->prev->next=p1;

p1->next=p;

p1=p->prev;

}

}

    }

}

return 1;

}

int readydata(){//进程里面是不是有就绪函数

pcb *p1;//当前位置

for(p=head;p!=NULL;p=p->next)

sum+=p->runtime;//进程队列中所有进程运行时间总计

for(i=0;i<sum;i++){

p1=head;

printf("第%d次:\n",i+1);

for(p=head;p!=NULL;p=p->next)

if(p->yxs<p1->yxs)

  p1=p;//找出链表中优先数最小的进程,运行该进程

p1->runtime--;//当前运行的进程运行时间减一

p1->yxs++;//当前运行的进程的优先数加一

if(p1->runtime==0){//如果运行时间减为0,则当前进程结束

printf("进程%s已结束.\n",p1->pname);

if(p1==head){

head=p1->next;

p1->next->prev=NULL;

p1->next=NULL;

}

else{

pcb *p2;

p2=p1;

p1->prev->next=p1->next;

p1->next->prev=p1->prev;

p1->next=NULL;

p1->prev=NULL;

}

}

    else{

    printf("当前进程:%s\n",p1->pname);

}

printf("队列中进程:");

for(p=head;p!=NULL;p=p->next)

if(p!=p1)

printf("%s  ",p->pname);

printf("\n");

}

}

int main(){

inputprocess();

printf("输入的进程为:\n");

for(p=head;p!=NULL;p=p->next)

printf("%s %d %d\n",p->pname,p->yxs,p->runtime);

readydata();//判断进程

return 1;

}


sort排序函数

#include<iostream>

#include<algorithm>

#include<string>

using namespace std;

//在c++库中引用了一个文件<algorithm>,里面定义的sort函数就是用来给给定区间排序的。

//这个小例子实践这里面最终是从小到大输出。

int main()

{

int a[10]={9,12,17,30,50,20,60,65,4,49};

sort(a,a+10);

for(int i=0;i<10;i++)

cout<<a[i]<<' ';

cout<<endl;

return 0;

}

上一篇下一篇

猜你喜欢

热点阅读