【實驗?zāi)康摹?/p>
在多道程序或者任務(wù)系統(tǒng)中,系統(tǒng)同時處于就緒狀態(tài)的進程有若干個。也就是說能運行的進程數(shù)遠遠大于處理機個數(shù),為了使系統(tǒng)中的各進程能有條不紊的運行窿给,必須選擇某種調(diào)度策略,以選擇一進程占用處理機率拒。這樣便要求我們來設(shè)計模擬進程調(diào)度的算法崩泡,來模擬實現(xiàn)計算機中的進程安排。此次實驗?zāi)M三種猬膨,先來先服務(wù)允华,優(yōu)先級調(diào)度,時間片輪轉(zhuǎn)。
【實驗原理】
[if !supportLists]1. [endif]首先是操作系統(tǒng)中
<1>.先來先服務(wù)調(diào)度靴寂,就是哪一個進程先到達的,它的優(yōu)先級就是最高召耘,優(yōu)點是實現(xiàn)簡單百炬,只需要根據(jù)arrivetime實現(xiàn)一個排序就行,缺點也是多多污它,不贅述了剖踊;按照優(yōu)先級調(diào)度的算法,這個算法里面衫贬,我們給進程安排了一個重要程度yxj德澈,按照這個排好隊,然后每執(zhí)行一次優(yōu)先級就下降固惯,這個實現(xiàn)就比較困難了梆造,體現(xiàn)在新的進程到來的插入,以及后面判斷就緒葬毫;時間片輪轉(zhuǎn)是一種比較好的算法镇辉,每個進程都可以排隊使用處理機,一開始的就緒隊列就是按照先來先服務(wù)排序的贴捡。
2.在實現(xiàn)中忽肛,用到了c語言中的指針數(shù)組知識,數(shù)據(jù)結(jié)構(gòu)中鏈表的知識烂斋,尤其是鏈表的操作(插入屹逛,改變順序等等)。體現(xiàn)了學(xué)科間的緊密結(jié)合與相互服務(wù)吧
【小結(jié)或討論】
這次的實驗感覺很有難度汛骂,實驗指導(dǎo)書上要求的數(shù)據(jù)結(jié)構(gòu)設(shè)計的鏈表指針已經(jīng)是大一知識了罕模,這也是自己很少鍛煉的原因。尤其是數(shù)據(jù)結(jié)構(gòu)香缺,本身難度就很大手销,需要再好好的看一遍,弄清楚排序图张,插入锋拖,指向等諸多問題。不過操作系統(tǒng)中的概念得到了理解記憶祸轮,尤其是第二個優(yōu)先級調(diào)度和第三個時間片兽埃,在處理進程后,優(yōu)先級如何變化适袜?這個進程要被插入到哪里柄错?這個時間片用完進程這么安排很多問題。
看書,看數(shù)據(jù)結(jié)構(gòu)以及操作系統(tǒng)課本售貌,想清楚進程的去向等基本問題给猾,多練習。
代碼:
輪轉(zhuǎn)調(diào)度:
#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;//進程狀態(tài)
struct pcb *next;//后繼指針
struct pcb *prev;//前驅(qū)指針
};
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();//建立進程函數(shù)
//int readyprocess();//建立就緒隊列函數(shù)
int readydata();//判斷進程是否就緒函數(shù)
//int runprocess();//運行進程函數(shù)
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已結(jié)束.\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颂跨,先來先服務(wù)
#include <iostream>
#include "string"
#include "algorithm"
using namespace std;
//進程類
class process{
public:
? ? string name;//進程名
? ? double arrive; //進程到達時刻
? ? double service;//進程服務(wù)時間
? ? 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;? ? ? ? ? ? ? ? ? //進程個數(shù)
? ? process pro[10];? ? ? ? //進程數(shù)組
? ? cout<<"請輸入c進程個數(shù): ";
? ? cin>>n;
? ? cout<<"請分別輸入這些進程的:\n進程名\t到達時刻\t服務(wù)時間\n";
? ? for(int i=0;i<n;i++){
? ? ? ? cin>>pro[i].name;
? ? ? ? cin>>pro[i].arrive;
? ? ? ? cin>>pro[i].service;
? ? }
? ? //"algorithm"文件里的sort函數(shù)
? ? sort(pro,pro+n,compare);? ? //s進程數(shù)組按到達時間從小到大排序
? ? cout<<"進程名\t到達時刻\t服務(wù)時間\t開始執(zhí)行時刻\t完成時刻\t周轉(zhuǎn)時間\t帶權(quán)周轉(zhuǎn)時間\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;? ? ? //周轉(zhuǎn)時間
? ? ? ? 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; //進程服務(wù)時間
? ? 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;
}
//比較兩個進程服務(wù)時間
bool compare2(process a,process b){
? ? return a.service<b.service;
}
int main(int argc, const char * argv[]) {
? ? int n;? ? ? ? ? ? ? ? ? //進程個數(shù)
? ? process pro[10];? ? ? ? //進程數(shù)組
? ? cout<<"請輸入c進程個數(shù): ";
? ? cin>>n;
? ? cout<<"請分別輸入這些進程的:\n進程名\t到達時刻\t服務(wù)時間\n";
? ? for(int i=0;i<n;i++){
? ? ? ? cin>>pro[i].name;
? ? ? ? cin>>pro[i].arrive;
? ? ? ? cin>>pro[i].service;
? ? }
? ? //"algorithm"文件里的sort函數(shù)
? ? sort(pro,pro+n,compare);? ? //s進程數(shù)組按到達時間從小到大排序
? ? cout<<"進程名\t到達時刻\t服務(wù)時間\t開始執(zhí)行時刻\t完成時刻\t周轉(zhuǎn)時間\t帶權(quán)周轉(zhuǎn)時間\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;? ? //周轉(zhuǎn)時間
? ? ? ? double dqzz=zz/pro[i].service;? //帶權(quán)周轉(zhuǎn)時間
? ? ? ? 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;
}
優(yōu)先級調(diào)度算法
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
struct pcb
{
char pname[5];//進程名
int yxs;//優(yōu)先數(shù)
int runtime;//估計運行時間
char state;//進程狀態(tài)
struct pcb *next;//后繼指針
struct pcb *prev;//前驅(qū)指針
};
//int num=5;//進程的個數(shù)
pcb *p; //定位到當前處理位置的指針
pcb *head; //頭指針指向頭節(jié)點
int sum=0;
int i,j,m;
char R='r',C='c';//進程的狀態(tài)
//unsigned long current=0;
int inputprocess();//建立進程函數(shù)
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個進程的優(yōu)先數(shù):",i+1);
scanf("%d",&(p1->yxs));
p1->state=R;
if(i==0)
{ //如果是插入第一個敢伸,直接插入即可
? ? ? p=p1;
? ? ? p->next=NULL;
? ? ? head=p;
}
else{//如果不是第一個,那么需要按照優(yōu)先數(shù)從小到大進行排序插入
p=head;
while((p!=NULL)&&(p->yxs<p1->yxs))
p=p->next;
? ? if(p==NULL){ //p==NULL
? ? p=head;//鏈表中優(yōu)先級都比現(xiàn)在要插入的高
? ? 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(){//進程里面是不是有就緒函數(shù)
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;//找出鏈表中優(yōu)先數(shù)最小的進程钓丰,運行該進程
p1->runtime--;//當前運行的進程運行時間減一
p1->yxs++;//當前運行的進程的優(yōu)先數(shù)加一
if(p1->runtime==0){//如果運行時間減為0躯砰,則當前進程結(jié)束
printf("進程%s已結(jié)束.\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排序函數(shù)
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
//在c++庫中引用了一個文件<algorithm>,里面定義的sort函數(shù)就是用來給給定區(qū)間排序的。
//這個小例子實踐這里面最終是從小到大輸出携丁。
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;
}