1. 程式人生 > >作業系統課程設計完成了

作業系統課程設計完成了

終於弄好了課程設計,不過不是自己做的

二:<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

設計要求:

編寫一程式,可以建立若干個虛擬程序,並對若干個虛擬程序進行排程,排程策略為時間片輪轉。

虛擬程式的描述:

虛擬指令的格式:操作命令操作時間

其中,操作命令有以下幾種:

lC : 表示在CPU上計算

lI :表示輸入

lO:表示輸出

lW:表示等待

lH:表示程序結束

操作時間代表該操作命令要執行多長時間

假設I/O裝置的數量沒有限制

IOW三條指令實際上是不佔用CPU的,執行這三條指令就應將程序放入對應的等待佇列(

Input等待佇列、Output等待佇列、Wait等待佇列)

例有一虛擬程式p1.prc描述如下:

c 30

o 12

c 9

i 14

h 0

該虛擬程式表示的含義是:先在CPU上計算30秒,再在輸出裝置上輸出12秒,計算9 秒,在輸入裝置上輸入14秒,程式結束。

實驗方法:

先用文字編輯器寫三個虛擬程式,可以分別命名為p1.prcp2.prcp3.prc。然後編一程序排程程式,將這三個虛擬程式建立成程序,並按各虛擬程序的指令要求執行和排程。用一個文字檔案,裡面只能放一個整數,表示一個時間因子,用於調節設計程式OS.EXE的執行速度。

執行結果要求:

要求在每個執行緒建立、佔用處理機、開始輸出、開始輸入和結束操作時分別顯示一行提示資訊,以確定所有處理都遵守相應的程序排程規則。

要求:

1.設計的分析,解決方案

2.程序的建立要建立程序控制塊(可參考UINX的程序控制塊的設計,要求有程序的必要資訊)

3.要有執行佇列、就緒佇列、Input等待佇列、Output等待佇列、Wait等待佇列

4.要有程序切換時的上下文轉換過程

5.要動態顯示每個程序的當前狀態及指令執行情況,動態顯示每個佇列的當前狀態

6.畫出程式的基本結構框圖和流程圖

7.對程式的每一部分要有詳細的設計分析說明,說明設計實現所用的原理,採用的資料結構

8.程序的各個操作函式的詳細說明(如建立程序,銷燬程序等)

9.原始碼格式規範,註釋不少於三分之一

10.對執行的結果要有結果的分析,

11.設計中遇到的問題,設計的心得體會

12.參考資料

13.開發工具不限

系統流程圖:

13 個作業

2. 按照時間片輪轉法實現程序排程

3.五個公用佇列

<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />

執行佇列

時間片

就緒等待佇列

CPU

C 時間片到等待結束 C

輸入等待佇列

I

H

結束

輸出等待佇列

O

阻塞等待佇列

W

源程式

#defineNULL 0

#include<stdio.h>

#include<string.h>

#include<malloc.h>

#include<time.h>

//定義一個pcb的結構體

FILE *GroupFile[10];

typedefstruct index{

charname;//指令

inttime;//指令執行時間

}index;

struct pcb {

char filename[10];//程序名

int id;//作業編號

int exetoIndex;//當前正在執行指令

char status;//當前狀態

int wtime;//等待時間

};

struct pcb jobpcb[100];//pcb

typedefstruct job{

index idx[100];//指令集

int pcbnum;//pcb編號對應

}job;

jobjobtab[100];//作業表

char jobp[3][50];//作業

//佇列

struct Qnode

{

intpcbnum[100];//pcb編號

inthead,tail;

};

structQnodeQueue[5];//5個佇列0E 1R2I 3O4W

voidinitqueue(struct Qnode *l);

//延遲

void delay(){

long begin,end;

time(&begin);

do {

time(&end);

} while((end-begin)<=1);

}

//字元轉化為數值

intchange(char *m){

int i,j=0;

int len=strlen(m);

for(i=0;i<len;i++)

j=j*10+m[i]-'0';

return j;

}

//申請 pcb

intAllocPCB(){

int i;

for(i=0;i<3;i++)

if(jobpcb[i].id ==-1)break;

if(i<3)

return i;

return -1;

}

//申請job

intAllocJob(){

int i;

for(i=0;i<3;i++)

if(jobtab[i].pcbnum == -1)break;

if(i<3)

return i;

return -1;

}

//顯示指令

void displayIndex(){

int i,j;

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

printf("Job% d /n",i+1);

for(j=0;j<10;j++)

printf("%d%c% d /n",j+1, jobtab[i].idx[j].name,jobtab[i].idx[j].time);

}

}

//建立程序程式

intcreatpcbline(){

charline[10];

inti,ll,jnum, pnum,ln=0,bpos, pos=0;

charbuff[50];

charname [20];

charch;

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

ln=0;

jnum=AllocJob();

if(jnum == -1) return 0;

pnum=AllocPCB();

if(pnum == -1) return 0;

jobtab[jnum].pcbnum=pnum;

strcpy(jobpcb[pnum].filename,"");

jobpcb[pnum].status='r';

jobpcb[pnum].exetoIndex=0;

jobpcb[pnum].id=jnum;

jobpcb[pnum].wtime=0;

int ln=strlen(jobp[i]);

pos=0;

while(pos<len){

while(jobp[i][pos]==' ') pos++;

jobtab[jnum].idx[ln].name=jobp[i][pos++];///

while(jobp[i][pos]==' ') pos++;

bpos=0;

while(jobp[i][pos]!=' ')

buff[bpos++]=jobp[i][pos++];

buff[bpos]='/0';

jobtab[jnum].idx[ln].time=change(buff);/////

if(pos<len) {pos++;ln++;

}

}

}

displayIndex();

}

/*初始化佇列

voidinitqueue(struct Qnode *l){

l->head=0;

l->tail=0;

}

//插進入佇列/

void insertqueue(struct Qnode *l,int pcbnum){

l->pcbnum[l->tail++]=pcbnum;

}

//佇列是否為空

int EmptyQueue( struct Qnode l){

if(l.head==l.tail) return 1;

return 0;

}

//刪除佇列

void outqueue(struct Qnode *l,int *pcbnum)

{

if (l->head>=l->tail ) *pcbnum=-1;

else

*pcbnum=l->pcbnum[l->head++];

}

//顯示作業

voiddisplay(){

int i,j;

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

printf(" 佇列%d",i);

for(j=Queue[i].head;j<Queue[i].tail;j++)

printf("pcb 編號%d/n/n",Queue[i].pcbnum[j]);

}

}

//作業入佇列

voidJobEnQueueInit( int * total){

int i,num ,Index=0;

char cmd;

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

if(jobpcb[i].id>=0){

cmd=jobtab[jobpcb[i].id].idx[Index].name;

switch(cmd){

case 'c':insertqueue(&Queue[1],i);jobpcb[i].status='r'; break;

case 'i':insertqueue(& Queue[2],i);jobpcb[i].status='i'; break;

case 'o':insertqueue(& Queue[3],i);jobpcb[i].status='o'; break;

case 'w':insertqueue(& Queue[4],i);jobpcb[i].status='w'; break;

case 'h':jobpcb[i].status='h'; num=jobpcb[i].id;jobtab[num].pcbnum=-1;jobpcb[i].id=-1;

}

if(cmd== 'h') {jobpcb[i].wtime=0;total--;}

jobpcb[i].wtime=jobtab [ jobpcb[i].id].idx[Index].time;

(*total)++;

}

}

}

voidsave (){

FILE *fp;

int i;

fp=fopen("pcbtable.txt","a");

fprintf(fp,"檔名作業編號執行到指令數所處狀態等待時間 /n" );

for(i=0;i<3;i++)

fprintf(fp," /t %s/t %d/t %d/t %c/t %d /n" ,

jobpcb[i].filename,jobpcb[i].id,jobpcb[i].exetoIndex,

jobpcb[i].status,jobpcb[i].wtime );

fclose(fp);

}

//作業入佇列

voidJobEnQueue( int pcbnum,int Index ,int *total){

int num;

char cmd;

if(jobpcb[pcbnum].id>=0){

cmd=jobtab[jobpcb[pcbnum].id].idx[Index].name;

switch(cmd){

case 'c':insertqueue(&Queue[1],pcbnum);jobpcb[pcbnum].status='r'; break;

case 'i':insertqueue(& Queue[2],pcbnum);jobpcb[pcbnum].status='i'; break;

case 'o':insertqueue(& Queue[3],pcbnum);jobpcb[pcbnum].status='o'; break;

case 'w':insertqueue(& Queue[4],pcbnum);jobpcb[pcbnum].status='w'; break;

case 'h':jobpcb[pcbnum].status='h'; num=jobpcb[pcbnum].id;jobtab[num].pcbnum=-1;jobpcb[pcbnum].id=-1;

}

if(cmd== 'h') {

jobpcb[pcbnum].wtime=0;

printf(" /n/t/t作業%d完成/n", pcbnum+1, jobpcb[ pcbnum].status);

(*total)--;

}

else jobpcb[pcbnum].wtime=jobtab [ jobpcb[pcbnum].id].idx[Index].time;

printf(" /n/t/t作業%d/n ", pcbnum+1);

printf("/t/t/t/t所處狀態 %c/n",jobpcb[ pcbnum].status);

printf("/t/t還需要時間%d/n",jobpcb[ pcbnum].wtime);

}

}

//得到佇列的首元素

intGetHead(struct Qnode l){

return l.pcbnum[l.head];

}

//執行

voidrun (){

int i, flag=0, time=10, pcbnum, Index=0, exenum, num, quenum;

char cmd;

int j,m,n;

int total=0;

JobEnQueueInit( &total );

save();

while(total!=0){

if(!EmptyQueue(Queue[1])){

outqueue(&Queue[1],&pcbnum);

insertqueue(&Queue[0], pcbnum);

elsepcbnum=GetHead(Queue[0]);

delay();

jobpcb[ pcbnum].status='e';

printf(" /n/t/t作業%d/n",pcbnum+1);

printf("/t/t/t所處狀態: %c /t執行了 %d /n", jobpcb[ pcbnum].status, time);

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

if(jobpcb[i].id>=0){

//所有的作業除在就緒佇列獲執行結束的外等待時間 都間時間片

if( jobpcb[i].status!='r'&&jobpcb[i].status!='h')jobpcb[i].wtime=jobpcb[i].wtime-time;

if(jobpcb[i].wtime<=0){//查詢所有的佇列 所在位置

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

for(m=Queue[j].head;m<Queue[j].tail;m++){

if(Queue[j].pcbnum[m]==i) {flag=1;break;}

}

if(flag==1) break;

}

if(flag==1){//刪除該指令

for(n=m;n<Queue[j].tail;n++) Queue[j].pcbnum[n]=Queue[j].pcbnum[n+1];

Queue[j].tail--;

jobpcb[i].exetoIndex++;

Index=jobpcb[i].exetoIndex;

JobEnQueue( i,Index,&total );

}

}

}

}

if(!EmptyQueue(Queue[1])){

outqueue(&Queue[0],&pcbnum);

if(jobpcb[pcbnum].wtime>0){

insertqueue(&Queue[1], pcbnum);

jobpcb[pcbnum].status='r';

}

}

printf(" /n/n/t/t 還有/t %d個作業沒有完成/n",total );

save();

}

}

//初始化

void InitFile(){

int i;

strcpy (jobp[0]," c 20i 20 o 15 h 0 ");////////////////////////

strcpy (jobp[1]," i 10 c 20 c 10 h 0 ");

strcpy (jobp[2]," c 30 i 20 c 5 h 0 ");

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

jobpcb[i].exetoIndex=0;

strcpy(jobpcb[i].filename,"");

jobpcb[i].id=-1;

jobpcb[i].status='r';

jobpcb[i].wtime=0;

}

for(i=0;i<100;i++)

jobtab[i].pcbnum=-1;

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

initqueue(&Queue[i]);

//GroupFile[0]=fopen("1.txt","r");

//GroupFile[1]=fopen("2.txt","r");

//GroupFile[2]=fopen("3.txt","r");

}

void main(){

InitFile();

creatpcbline();

run ();

}

設計說明

這個程式分了三部分,初始化,建立程序,執行程序,我們三個人分開做,我主要做建立程序的一個函式

即主函式中的 creatpcbline();

設計心得

作業系統是計算機系統中必不可少的系統軟體。它是計算機系統中各種資源的管理者和各種活動的組織者、指揮者。作業系統採用時間片法排程程序,使系統資源得到充分的利用,使用者也可以花更少的時間完成更多的工作,這次模擬系統排程程序,讓我明白了系統時間片的排程方法,對作業系統理論的學習更加深一層.