作業系統課程設計完成了
終於弄好了課程設計,不過不是自己做的
二:<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
設計要求:
編寫一程式,可以建立若干個虛擬程序,並對若干個虛擬程序進行排程,排程策略為時間片輪轉。
虛擬程式的描述:
虛擬指令的格式:操作命令操作時間
其中,操作命令有以下幾種:
lC : 表示在CPU上計算
lI :表示輸入
lO:表示輸出
lW:表示等待
lH:表示程序結束
操作時間代表該操作命令要執行多長時間
假設I/O裝置的數量沒有限制
I、O、W三條指令實際上是不佔用CPU的,執行這三條指令就應將程序放入對應的等待佇列(
例有一虛擬程式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.開發工具不限
系統流程圖:
1.3 個作業
2. 按照時間片輪轉法實現程序排程
3.五個公用佇列
<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />
執行佇列 |
時間片 |
就緒等待佇列 |
CPU |
輸入等待佇列 |
H
結束 |
輸出等待佇列 |
阻塞等待佇列 |
源程式
#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();
設計心得:
作業系統是計算機系統中必不可少的系統軟體。它是計算機系統中各種資源的管理者和各種活動的組織者、指揮者。作業系統採用時間片法排程程序,使系統資源得到充分的利用,使用者也可以花更少的時間完成更多的工作,這次模擬系統排程程序,讓我明白了系統時間片的排程方法,對作業系統理論的學習更加深一層.