版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領
文檔簡介
實驗一項目名稱:熟悉使用計算機系統(tǒng)實驗題目要求確定兩組初值,運行設計的程序,顯示或打印每一組的A和AT。編制一個程序,求10′10矩陣A的轉(zhuǎn)置矩陣AT,即二、流程圖運行主函數(shù)定義主函數(shù)結(jié)束開始運行主函數(shù)定義主函數(shù)結(jié)束開始源程序代碼#include<stdio.h>
intmain(){
intarray[10][10],array[10][10];
inti,j;//輸入矩陣printf("Transposedbefore\n");
for(i=0;i<10;i++){
for(j=0;j<10;j++){
scanf("%d",&a[i][j]);//scanf可以替換成相應的隨機函數(shù)}
}
//轉(zhuǎn)置矩陣printf("*************************************\n");
for(i=0;i<10;i++)
for(j=0;j<10;j++){
array[j][i]=a[i][j];
}
//輸出轉(zhuǎn)置后的矩陣printf("Transposedafter\n");
for(i=0;i<10;i++){
for(j=0;j<10;j++){
printf("%d",array[i][j]);
}
printf("\n");
}
system("pause");
return0;
}實驗結(jié)果截圖A矩陣:AT矩陣:二者進行轉(zhuǎn)置后結(jié)果為:實驗總結(jié)這次是操作系統(tǒng)第一次上機實驗,所以主要是熟悉使用計算機系統(tǒng),然后編一個轉(zhuǎn)置矩陣,可以用c語言,也可以用c++等語言編程。本實驗用c語言編,讓我重新溫習到了所學的知識,雖然過程中有很多不懂,但經(jīng)過詢問同學以及查閱相關書籍,理清了編程思路,畫出流程圖,終于完成了本實驗內(nèi)容,一個10*10的矩陣的轉(zhuǎn)置。從這次實驗中,我知道了光弄懂書本的內(nèi)容是遠遠不夠的,還得用實踐證明,從實踐中學習到更多的知識,鞏固更多的理論知識。實驗二項目名稱:處理器調(diào)度一、實驗題目設計一個按優(yōu)先數(shù)調(diào)度算法實現(xiàn)處理器調(diào)度的程序。[提示]:(1)假定系統(tǒng)有五個進程,每一個進程用一個進程控制塊PCB來代表,進程控制塊的格式為:進程名指針要求運行時間優(yōu)先數(shù)狀態(tài)其中,進程名——作為進程的標識,假設五個進程的進程名分別為P1,P2,P3,P4,P5。指針——按優(yōu)先數(shù)的大小把五個進程連成隊列,用指針指出下一個進程的進程控制塊的首地址,最后一個進程中的指針為“0”。要求運行時間——假設進程需要運行的單位時間數(shù)。優(yōu)先數(shù)——賦予進程的優(yōu)先數(shù),調(diào)度時總是選取優(yōu)先數(shù)大的進程先執(zhí)行。狀態(tài)——可假設有兩種狀態(tài),“就緒”狀態(tài)和“結(jié)束”狀態(tài)。五個進程的初始狀態(tài)都為“就緒”,用“R”表示,當一個進程運行結(jié)束后,它的狀態(tài)為“結(jié)束”,用“E”表示。(2)在每次運行你所設計的處理器調(diào)度程序之前,為每個進程任意確定它的“優(yōu)先數(shù)”和“要求運行時間”。(3)為了調(diào)度方便,把五個進程按給定的優(yōu)先數(shù)從大到小連成隊列。用一單元指出隊首進程,用指針指出隊列的連接情況。二、程序中使用的數(shù)據(jù)結(jié)構(gòu)及符號說明:#definenum5//假定系統(tǒng)中進程個數(shù)為5structPCB{charID;//進程名intruntime;//要求運行時間intpri;//優(yōu)先數(shù)charstate;//狀態(tài),R-就緒,F(xiàn)-結(jié)束};structPCBpcblist[num];//定義進程控制塊數(shù)組三、流程圖:主程序流程圖:開始開始結(jié)束調(diào)用運行子程序調(diào)用初始化子程序結(jié)束調(diào)用運行子程序調(diào)用初始化子程序(2)子程序init()流程圖:開始開始定義ii=0i<num輸出操作提示輸入ID,pri,runtimestate=’R’getchar()結(jié)束i=i+1(3)子程序max_pri_process()流程圖:開始開始定義i,key,max=100i=0i<numpcblist[i].state==’r’max<pcblist[i].pri&&pcblist[i].state=='R'max=pcblist[i].prikey=ipcblist[key].state=='F'return-1returnkey結(jié)束return-1i=i+1(4)子程序show()流程圖:開始開始定義i輸出提示i=0i<num輸出pcblist[i]的ID,pri,runtime,state提示按鍵繼續(xù)i=i+1結(jié)束子程序run()流程圖:開始開始定義i,j,tj=0j<numt+=pcblist[j].runtimej=j+1輸出提示show()getchar()j<tmax_pri_process()!=-1j=0pcblist[max_pri_process()].state='r'i=0i=0i<numpcblist[i].state=='r'pcblist[i].pri-=1pcblist[i].runtime--pcblist[i].runtime==0pcblist[i].state='F'pcblist[i].state='R'show()getchar()i=i+1j=j+1結(jié)束源程序代碼#include"stdio.h"#include"string.h"#definenum5//假定系統(tǒng)中進程個數(shù)為5structPCB{charID;//進程名intruntime;//要求運行時間intpri;//優(yōu)先數(shù)charstate;//狀態(tài),R-就緒,F(xiàn)-結(jié)束};structPCBpcblist[num];//定義進程控制塊數(shù)組voidinit(){//PCB初始化子程序inti;for(i=0;i<num;i++){printf("PCB[%d]:IDpriruntime\n",i+1);//為每個進程任意指定pri和runtimescanf("%s%d%d",&pcblist[i].ID,&pcblist[i].pri,&pcblist[i].runtime);pcblist[i].state='R';//進程初始狀態(tài)均為就緒getchar();//接收回車符}}intmax_pri_process(){//確定最大優(yōu)先級進程子程序intmax=-100;//max為最大優(yōu)先數(shù),初始化為-100inti;intkey;for(i=0;i<num;i++){if(pcblist[i].state=='r')//r為輔助狀態(tài)標志,表示正在運行return-1;//返回-1else if(max<pcblist[i].pri&&pcblist[i].state=='R')//從就緒進程中選取優(yōu)先數(shù)最大的進程 {max=pcblist[i].pri;//max存放每次循環(huán)中的最大優(yōu)先數(shù)key=i;//將進程號賦給key }}if(pcblist[key].state=='F')//具有最大優(yōu)先數(shù)的進程若已運行完畢 return-1;//則返回-1else//否則 returnkey;//將key作為返回值返回}voidshow()//顯示子程序{inti;printf("\nIDpriruntimestate\n");printf("-------------------------------------------------\n");for(i=0;i<num;i++){//依次顯示每個進程的名、優(yōu)先數(shù)、要求運行時間和狀態(tài)printf("%s%6d%8d%s\n",&pcblist[i].ID,pcblist[i].pri,pcblist[i].runtime,&pcblist[i].state);}printf("pressanykeytocontinue...\n");}voidrun(){//進程運行子程序inti,j;intt=0;//t為運行次數(shù)for(j=0;j<num;j++){t+=pcblist[j].runtime;}//運行次數(shù)即為各個進程運行時間之和printf("\nbeforerun,theconditonis:\n");show();//調(diào)用show()子程序顯示運行前PCB的情況getchar();//等待輸入回車符for(j=0;j<t;j++){while(max_pri_process()!=-1)//具有最大優(yōu)先數(shù)的進程沒有運行完,讓其運行{ pcblist[max_pri_process()].state='r';//將其狀態(tài)置為r,表示其正在運行}for(i=0;i<num;i++){if(pcblist[i].state=='r'){pcblist[i].pri-=1;//將當前運行進程的優(yōu)先數(shù)減1pcblist[i].runtime--;{//要求運行時間減1if(pcblist[i].runtime==0) pcblist[i].state='F';//運行完則將該進程狀態(tài)置為結(jié)束 elsepcblist[i].state='R';//未運行完將其狀態(tài)置為就緒 } show();//顯示每次運行后各PCB的情況getchar();//等待回車進入下一次運行} }}}voidmain(){//按動態(tài)優(yōu)先數(shù)調(diào)度主程序init();//初始化各個進程PCBrun();//進程調(diào)度模擬}實驗結(jié)果截圖實驗總結(jié)這次是操作系統(tǒng)第二次上機實驗,主要是選擇一個調(diào)度算法,實現(xiàn)處理器調(diào)度,可以用c語言,也可以用c++等語言編程。本實驗用c++編,讓我重新溫習到了所學的知識,雖然過程中有很多不懂,但經(jīng)過詢問同學以及查閱相關書籍,理清了編程思路,畫出流程圖,終于完成了本實驗內(nèi)容,一個按優(yōu)先數(shù)調(diào)度算法實現(xiàn)處理器調(diào)度的程序。從這次實驗中,我知道了光弄懂書本的內(nèi)容是遠遠不夠的,還得用實踐證明,從實踐中學習到更多的知識,鞏固更多的理論知識。實驗三項目名稱:模擬批處理多道操作系統(tǒng)的作業(yè)調(diào)度。采用先來先服務算法和運行時間最短者優(yōu)先算法模擬設計作業(yè)調(diào)度程序。[提示]:(1)作業(yè)調(diào)度程序負責從輸入井選擇若干個作業(yè)進入主存,為它們分配必要的資源,當它們能夠被進程調(diào)度選中時,就可占用處理器運行。作業(yè)調(diào)度選擇一個作業(yè)的必要條件是系統(tǒng)中現(xiàn)有的尚未分配的資源可滿足該作業(yè)的資源要求。但有時系統(tǒng)中現(xiàn)有的尚未分配的資源既可滿足某個作業(yè)的要求也可滿足其它一些作業(yè)的要求,那么,作業(yè)調(diào)度必須按一定的算法在這些作業(yè)中作出選擇。先來先服務算法是按照作業(yè)進入輸入井的先后次序來挑選作業(yè),先進入輸入井的作業(yè)優(yōu)先被挑選,當系統(tǒng)中現(xiàn)有的尚未分配的資源不能滿足先進入輸入井的作業(yè)時,那么順序挑選后面的作業(yè)。運行時間最短者優(yōu)先算法總是按作業(yè)要求運行的時間來選擇作業(yè),每次挑選要求運行時間短且資源要求能滿足的作業(yè)先進入主存執(zhí)行。(2)為了表示暫存在輸入井中的各個作業(yè)的情況(作業(yè)信息在輸入井中的位置、作業(yè)的資源要求等),常常采用二級目錄結(jié)構(gòu):作業(yè)表和預輸入表。二、程序中使用的數(shù)據(jù)結(jié)構(gòu)及符號說明:設計一個結(jié)構(gòu)體數(shù)組typedefstructwork{ charusername[10];//用戶名 charworkname[10];//作業(yè)名 floattime;//作業(yè)運行時間 charstate;//狀態(tài)R為收容,A表示執(zhí)行狀態(tài),T為完成 intstore;//主存 inttape;//磁帶 }WORK;WORKw[N];//工作數(shù)組初始化操作printf("初始化:\n"); for(i=0;i<N;i++){ printf("--請輸入第%d個作業(yè)的信息--\n",i+1); printf("第%d個作業(yè):用戶名:",i+1); scanf("%s",w[i].username); printf("第%d個作業(yè):作業(yè)名:",i+1); scanf("%s",w[i].workname); printf("第%d個作業(yè):運行時間:",i+1); scanf("%f",&w[i].time); printf("第%d個作業(yè):狀態(tài):",i+1); scanf("%s",&w[i].state); printf("第%d個作業(yè):主存:",i+1); scanf("%d",&w[i].store); printf("第%d個作業(yè):磁帶:",i+1); scanf("%d",&w[i].tape); }源程序代碼#include<stdio.h>#include<stdlib.h>#include<string.h>#include<time.h>#defineN5//作業(yè)數(shù)#defineT5//資源數(shù)#defineS100//主存大小typedefstructwork{ charusername[10];//用戶名 charworkname[10];//作業(yè)名 floattime;//作業(yè)運行時間 charstate;//狀態(tài)R為收容,Z表示執(zhí)行狀態(tài),W為完成 intstore;//主存 inttape;//磁帶}WORK;intSJF();//運行時間最短者優(yōu)先算法intFCFS();//先來先服務intchoiceWork();//選擇一個"收容狀態(tài)",資源能滿足的作業(yè)voidAdminister();//執(zhí)行程序intt=T;//m為系統(tǒng)中剩余的磁帶資源量ints=S;//s為主存剩余大小WORKw[N];//工作數(shù)組voidmain(){ inti; printf("初始化:\n"); for(i=0;i<N;i++){ printf("--請輸入第%d個作業(yè)的信息--\n",i+1); printf("第%d個作業(yè):用戶名:",i+1); scanf("%s",w[i].username); printf("第%d個作業(yè):作業(yè)名:",i+1); scanf("%s",w[i].workname); printf("第%d個作業(yè):運行時間:",i+1); scanf("%f",&w[i].time); printf("第%d個作業(yè):狀態(tài):",i+1); scanf("%s",&w[i].state); printf("第%d個作業(yè):主存:",i+1); scanf("%d",&w[i].store); printf("第%d個作業(yè):磁帶:",i+1); scanf("%d",&w[i].tape); }Administer();//執(zhí)行程序}voidAdminister(){//執(zhí)行程序 inti,j,f; intn=0;//主存中的作業(yè)數(shù)for(i=0;i<N;i++) if(w[i].state=='Z'){ t=t-w[i].tape; s=s-w[i].store; n++; } if(s<0||t<0||n>2){ printf("初始化失敗,退出系統(tǒng)\n"); return; } charworkname[10]; charusername[10]; for(;;){ floatp; intk; intq; charb; getchar(); time_tt; srand((unsigned)time(&t)); printf("電腦隨機數(shù)是:\n"); for(k=0;k<1;k++) q=rand()%10; p=q*0.1; printf("%f\n",p); if(p>0.5){ printf("隨機數(shù)大于0.5,轉(zhuǎn)入作業(yè)表\n"); } else{ printf("隨機數(shù)不大于0.5,轉(zhuǎn)入主存\n"); } printf("繼續(xù)(N)、返回(B)、顯示當前著作業(yè)狀態(tài)(D)還是退出系統(tǒng)(Q):"); scanf("%s",&b); if(b=='N'){ if(p>0.5&&p<=1){ f=0; for(i=0;i<N;i++) if(w[i].state=='R') f=1; if(f==1){//主存中尚有未被選中的作業(yè) if(t>0&&s>0){//主存中還能裝入作業(yè) j=choiceWork(); if(j<0){//沒選到 printf("等待作業(yè)執(zhí)行結(jié)束歸還資源.\n"); continue; } else{//為作業(yè)分配資源 t=t-w[j].tape; s=s-w[j].store; w[j].state='Z'; n++; if(n>2) {t=t+w[j].tape; s=s+w[j].store; w[j].state='R'; n++; printf("主存無法正常運行,返回.\n"); continue; }printf("--顯示被調(diào)入主存的作業(yè)的用戶名和作業(yè)名--\n"); printf("%s%s\n",w[j].username,w[j].workname); continue; } } else{ printf("主存中作業(yè)滿載.\n"); continue; } } else{ printf("請操作員輸入作業(yè).\n"); } } else{ if(n==2){ floath=0; floatl=100; intH=-1; intL=-1; for(i=0;i<N;i++) if(w[i].state=='Z'&&w[i].time>h){h=w[i].time; H=i; } elseif(w[i].state=='Z'&&w[i].time<l){ H=w[i].time; L=i; } if(H>L){ for(i=0;i<N;i++) if(w[i].state=='Z'){ printf("作業(yè)%s正在執(zhí)行.\n",w[i].workname); printf("輸入用戶名(該作業(yè)結(jié)束):",i); scanf("%s",username); printf("輸入作業(yè)名(該作業(yè)結(jié)束):",i); scanf("%s",workname); } for(i=0;i<N;i++) if(strcmp(workname,w[i].workname)==0){ w[i].state='W'; s+=w[i].store; t+=w[i].tape; n=0; break; } } else{ for(i=N-1;i>-1;i--) if(w[i].state=='Z'){ printf("作業(yè)%s正在執(zhí)行.\n",w[i].workname); printf("輸入用戶名(該作業(yè)結(jié)束):",i); scanf("%s",username); printf("輸入作業(yè)名(該作業(yè)結(jié)束):",i); scanf("%s",workname); } for(i=N-1;i>-1;i--) if(strcmp(workname,w[i].workname)==0){ w[i].state='W'; s+=w[i].store; t+=w[i].tape; n=0; break; } } continue; } elseif(n==1){for(i=0;i<N;i++)//輸出正在執(zhí)行的作業(yè) if(w[i].state=='Z'){ printf("作業(yè)%s正在執(zhí)行.\n",w[i].workname); printf("輸入用戶名(該作業(yè)結(jié)束):",i); scanf("%s",username); printf("輸入作業(yè)名(該作業(yè)結(jié)束):",i); scanf("%s",workname); } for(i=0;i<N;i++) if(strcmp(workname,w[i].workname)==0){ w[i].state='W'; s+=w[i].store; t+=w[i].tape; n=0; break; } continue;} else{ printf("主存中沒有作業(yè).\n"); continue; } } } if(b=='B'){ printf("返回重新隨即.\n"); continue; } if(b=='Q'){ break; } if(b=='D'){ printf("--顯示眾作業(yè)當前的信息--\n",i+1); printf("用戶名\t作業(yè)名\t運行時間\t狀態(tài)\t主存\t磁帶\n"); for(i=0;i<N;i++){ printf("%s\t%s\t%f\t%s\t%d\t%d\n",w[i].username,w[i].workname,w[i].time,&w[i].state,w[i].store,w[i].tape); } } }}intchoiceWork()//選擇一個"收容狀態(tài)",資源能滿足的作業(yè){ inti; charc; getchar(); printf("用先來先服務算法,或者用運行時間最短者優(yōu)先算法ForS:"); scanf("%c",&c); switch(c) { case'F':i=FCFS();break; case'S':i=SJF();break; } returni;}intFCFS()//先來先服務{(diào) inti; for(i=0;i<N;i++)//查找工作狀態(tài)為"收容"的資源量可滿足的作業(yè) if(w[i].state=='R'&&w[i].store<=s&&w[i].tape<=t) break; if(i>=0&&i<N) returni; else return-1;}intSJF()//運行時間最短者優(yōu)先算法{ inti,j=-1; floatk=100;//100為任意給的值,可以換任意的大于最長作業(yè)時間的數(shù) for(i=0;i<N;i++) if(w[i].state=='R'&&w[i].store<=s&&w[i].tape<=t&&w[i].time<k) { k=w[i].time; j=i; } returnj;}四、實驗結(jié)果截圖五、實驗總結(jié)通過此次實驗不僅鞏固了作業(yè)調(diào)度還把處理器調(diào)度算法進一步熟練運用了。通過對作業(yè)調(diào)度處理算法的研究使我對主存的工作方式有了進一步的認識,對以后從事工作會有很大的幫助,通過用c語言來實現(xiàn)程序是我進一步熟練了編程步驟在提高自己動手能力的同時還加強了知識掌握熟練度。剛開始我的作業(yè)調(diào)度程序很簡單,只能滿足部分功能。對隨機函數(shù)和多道作業(yè)的撤離沒有編寫,這星期張老師給我們這組講解了作業(yè)調(diào)度的流程圖和重點框架,讓我加深了對調(diào)度的理解,并進一步完善了程序。雖然在這里邊遇到一些問題但經(jīng)過自己的努力最后都迎刃而解,大大的增強了自己的自信心。總之在這次課程設計過程中,通過自己不懈的努力我從中受益匪淺。實驗四項目名稱:同步機構(gòu)---------模擬實現(xiàn)用同步機構(gòu)避免發(fā)生進程執(zhí)行時可能出現(xiàn)的與時間有關的錯誤實驗題目模擬PV操作同步機構(gòu),且用PV操作解決生產(chǎn)者——消費者問題。二、程序中使用的數(shù)據(jù)結(jié)構(gòu)及符號說明:typedefstructPcb{ charname[10];//進程名 charstate[10];//運行狀態(tài) charreason[10];//若阻塞,其原因 intbreakp;//斷點保護 structPcb*next;//阻塞時的順序進程名狀態(tài)等待原因斷點后繼進程}Pcb,*link;進程控制塊結(jié)構(gòu)定義兩個進程:linkp1;//生產(chǎn)者進程,linkc1;//消費者進程。pc程序計數(shù)器和linkready;就緒隊列,linkb_s1;s1阻塞隊列,linkb_s2;s2阻塞隊列。源程序代碼分為四個頭文件。1、a.h頭文件代碼如下:#include<string.h>#include<ctype.h>#include<malloc.h>/*malloc()等*/#include<limits.h>/*INT_MAX等*/#include<stdio.h>/*EOF(=^Z或F6),NULL*/#include<stdlib.h>/*atoi()*/#include<io.h>/*eof()*/#include<math.h>/*floor(),ceil(),abs()*/#include<process.h>/*exit()*/#include<iostream>usingnamespacestd;#include<time.h>#defineBUF10//緩存的大小#defineMAX20//最大可以輸入的字符2、b.h頭文件代碼如下://數(shù)據(jù)結(jié)構(gòu)的定義和全局變量typedefstructPcb{ charname[10];//進程名 charstate[10];//運行狀態(tài) charreason[10];//若阻塞,其原因 intbreakp;//斷點保護 structPcb*next;//阻塞時的順序}Pcb,*link;ints1,s2;//信號量linkp1;//生產(chǎn)者進程linkc1;//消費者進程charstr[MAX];//輸入的字符串charbuffer[BUF];//緩沖池intlen;//輸入長度intsp=0;//string的指針intin=0;//生產(chǎn)者指針intout=0;//消費者指針chartemp;//供打印的臨時產(chǎn)品charrec_p[MAX];//生產(chǎn)記錄intrp1=0;//生產(chǎn)記錄指針charrec_c[MAX];//消費記錄intrp2=0;//消費記錄指針linkready;//就緒隊列l(wèi)inkb_s1;//s1阻塞隊列l(wèi)inkb_s2;//s2阻塞隊列intpc;//程序計數(shù)器intcount;//字符計數(shù)器intcon_cnt;//消費計數(shù)器3、c.h頭文件代碼如下:voidinit();//初始化voidp(ints);//P操作voidv(ints);//V操作voidblock(ints);//阻塞函數(shù)voidwakeup(ints);//喚醒函數(shù)voidcontrol();//處理機調(diào)度voidprocessor();//處理機執(zhí)行voidprint();//打印函數(shù)voidinit(){//初始化 s1=BUF; s2=0; p1=(link)malloc(sizeof(Pcb));//建立新的結(jié)點,并初始化為生產(chǎn)者 strcpy(p1->name,"Producer"); strcpy(p1->state,"Ready"); strcpy(p1->reason,"Null"); p1->breakp=0; p1->next=NULL; c1=(link)malloc(sizeof(Pcb));//建立新的結(jié)點,并初始化為消費者 strcpy(c1->name,"Consumer"); strcpy(c1->state,"Ready"); strcpy(c1->reason,"Null"); c1->breakp=0; c1->next=NULL; ready=p1; ready->next=c1;//初始化為生產(chǎn)進程在前,消費進程在后 c1->next=NULL; b_s1=NULL; b_s2=NULL;//阻塞進程為NULL pc=0; con_cnt=0;//消費計數(shù)器}voidp(ints){ if(s==1){//p(s1) s1--; if(s1<0) block(1);//阻塞當前生產(chǎn)進程 else{ printf("\t*s1信號申請成功!\n"); ready->breakp=pc;//保存斷點 } } else{//p(s2) s2--; if(s2<0) block(2);//阻塞當前消費進程 else{ printf("\t*s2信號申請成功!\n"); ready->breakp=pc;//保存斷點 } }}voidv(ints){ if(s==1){//v(s1) s1++; if(s1<=0) wakeup(1);//喚醒生產(chǎn)進程 ready->breakp=pc;//保存斷點 } else{//v(s2) s2++; if(s2<=0) wakeup(2);//喚醒消費進程 ready->breakp=pc;//保存斷點 }}voidblock(ints){//阻塞函數(shù)的定義 linkp; intnum1=0; intnum2=0; if(s==1){//生產(chǎn)進程 strcpy(p1->state,"Block");//改變狀態(tài) strcpy(p1->reason,"S1");//說明原因 p=b_s1; while(p){ num1++; p=p->next;//p的值為NULL,表示隊尾 } if(!b_s1) b_s1=p1; else p=p1; p1->next=NULL; printf("\t*p1生產(chǎn)進程阻塞了!\n"); ready->breakp=pc;//保存斷點 ready=ready->next;//在就緒隊列中去掉,指向下一個 num1++; } else{//消費進程 strcpy(c1->state,"Block"); strcpy(c1->reason,"S2"); p=b_s2; while(p){ num2++; p=p->next;//p的值為NULL,表示隊尾 } if(!b_s2) b_s2=c1; else p=c1; ready->breakp=pc;//保存斷點 ready=ready->next;//在就緒隊列中去掉,指向下一個 c1->next=NULL; printf("\t*c1消費進程阻塞了!\n"); num2++; } printf("\t*阻塞的生產(chǎn)進程個數(shù)為:%d\n",num1); printf("\t*阻塞的消費進程個數(shù)為:%d\n",num2);}voidwakeup(ints){//喚醒函數(shù)的定義 linkp; linkq=ready; if(s==1){//喚醒b_s1隊首進程,生產(chǎn)進程隊列 p=b_s1; b_s1=b_s1->next;//阻塞指針指向下一個阻塞進程 strcpy(p->state,"Ready"); strcpy(p->reason,"Null"); while(q)//插入就緒隊列 q=q->next; q=p; p->next=NULL; printf("\t*p1生產(chǎn)進程喚醒了!\n"); } else{//喚醒b_s2隊首進程,消費進程隊列 p=b_s2; b_s2=b_s2->next;//阻塞指針指向下一個阻塞進程 strcpy(p->state,"Ready"); strcpy(p->reason,"Null"); while(q->next)//插入就緒隊列 q=q->next; q->next=p; p->next=NULL; printf("\t*c1消費進程喚醒了!\n"); }}voidcontrol()//處理器調(diào)度程序{ intrd; intnum=0; linkp=ready;if(ready==NULL)//若無就緒進程,結(jié)束 return; while(p)//統(tǒng)計就緒進程個數(shù) { num++; p=p->next;//最終p變?yōu)镹ULL } printf("\t*就緒進程個數(shù)為:%d\n",num); time_tt; srand((unsigned)time(&t)); rd=rand()%num;//隨機函數(shù)產(chǎn)生隨機數(shù) if(rd==1){ p=ready; ready=ready->next; ready->next=p; p->next=NULL; strcpy(ready->state,"Run"); strcpy(ready->next->state,"Ready"); } else strcpy(ready->state,"Run"); pc=ready->breakp;}voidprocessor(){//模擬處理器指令執(zhí)行 if(strcmp(ready->name,"Producer")==0)//當前進程為生產(chǎn)者 switch(pc) {case0://produce printf("\t*生產(chǎn)者生產(chǎn)了字符%c\n",str[sp]); rec_p[rp1]=str[sp];//添加到生產(chǎn)記錄 sp=(sp+1)%len; pc++; ready->breakp=pc;//保存斷點 break; case1://p(s1) pc++; p(1); break; case2://put buffer[in]=rec_p[rp1];//放到緩沖區(qū) printf("\t*%c字符成功入駐空緩存!\n",buffer[in]); rp1++; in=(in+1)%BUF; pc++; ready->breakp=pc;//保存斷點 break; case3://v(s2) pc++; printf("\t*釋放一個s2信號\n"); v(2); break; case4://goto01 printf("\t*生產(chǎn)進程goto0操作\n"); pc=0; count--;//剩余字符個數(shù)減1 printf("\t*剩余字符count=%d個\n",count); ready->breakp=pc;//保存斷點 if(count<=0){//生產(chǎn)結(jié)束 printf("\t*生產(chǎn)者結(jié)束生產(chǎn)!\n"); strcpy(p1->state,"Stop"); strcpy(p1->reason,"Null"); ready->breakp=-1; ready=ready->next;//在就緒隊列中去掉 } } else//當前進程為消費者 switch(pc) { case0://p(s2) pc++; p(2); break; case1://get printf("\t*消費者取字符!\n"); temp=buffer[out]; out=(out+1)%BUF; pc++; ready->breakp=pc;//保存斷點 break; case2://v(s1) pc++; printf("\t*釋放一個s1\n"); v(1); break; case3://consume printf("\t*消費了字符%c\n",temp); rec_c[rp2]=temp;//添加到消費記錄 rp2++; con_cnt++; if(con_cnt>=len){ strcpy(c1->state,"Stop");//完成態(tài) c1->breakp=-1; return; } pc++; ready->breakp=pc;//保存斷點 break; case4://goto0 printf("\t*消費進程goto0操作\n"); pc=0; ready->breakp=pc;//保存斷點 }}voidprint(){ inti,j; printf("————————生產(chǎn)者消費者模擬———————\n"); printf("*模擬過程的字符串為:\t"); printf("%s\n",&str); printf("*已生產(chǎn):"); for(j=0;j<=rp1;j++) printf("%c",rec_p[j]); printf("\n*空緩存:"); for(j=rp2;j<=rp1;j++) printf("%c",buffer[j]); printf("\n*已消費:"); for(j=0;j<=rp2;j++) printf("%c",rec_c[j]); printf("\n———————進程控制塊的信息————————\n"); printf("進程名\t\t狀態(tài)\t等待原因\t斷點\n"); printf("%s\t%s\t%s\t\t%d\n\n",p1->name,p1->state,p1->reason,p1->breakp); printf("%s\t%s\t%s\t\t%d\n",c1->name,c1->state,c1->reason,c1->breakp); printf("———————————————————————\n"); printf("1.繼續(xù)0.退出\n"); scanf("%d",&i); if(i==0){ exit(0); }}4、main頭文件代碼如下:#include"a.h"#include"b.h"#include"c.h"voidmain(){ printf("*生產(chǎn)者消費者模擬\n"); printf("—————————\n"); printf("*請輸入字符串:\n"); scanf("%s",str);//string數(shù)組存放將要產(chǎn)生的字符 len=strlen(str); count=len;//輸入字符的個數(shù) init();//初始化 while(con_cnt<len)//消費完所有的字符為結(jié)束 { system("cls");//清屏操作 printf("—————————模擬指令流程————————\n"); control();//處理器調(diào)度程序 processor();//模擬處理器指令執(zhí)行 print();//輸出顯示各個信息 }printf("\n程序結(jié)束!\n");}實驗結(jié)果截圖五、實驗總結(jié)這次是操作系統(tǒng)第四次上機實驗,主要是模擬實現(xiàn)用同步機構(gòu)避免發(fā)生進程執(zhí)行時可能出現(xiàn)的與時間有關的錯誤,可以用c語言,也可以用c++等語言編程。本實驗用c++編,讓我重新溫習到了所學的知識,雖然過程中有很多不懂,但經(jīng)過詢問同學以及查閱相關書籍,理清了編程思路,畫出流程圖,終于完成了本實驗內(nèi)容,一個模擬PV操作同步機構(gòu),且用PV操作解決生產(chǎn)者——消費者問題的程序。從這次實驗中,我知道了光弄懂書本的內(nèi)容是遠遠不夠的,還得用實踐證明,從實踐中學習到更多的知識,鞏固更多的理論知識。實驗五項目名稱:資源分配實驗題目用按序分配策略實現(xiàn)資源分配。要求:(1)設計一個3個進程共享10個資源的系統(tǒng),進程可動態(tài)地申請資源和釋放資源,系統(tǒng)按各進程的申請動態(tài)地分配資源。(2)設計用按序分配算法實現(xiàn)資源分配的資源分配程序,應具有顯示或打印各進程依次要求申請的資源號以及依次分配資源地情況。(3)確定兩組各進程依次要求申請的資源號,要求其中的一組中各進程按序地申請資源,另一組中各進程申請資源不受序號限制,分別運行上述設計的資源分配程序,觀察運行結(jié)果。二、程序中使用的數(shù)據(jù)結(jié)構(gòu)及符號說明:#defineI3#defineN10intready=0;//進程為就緒態(tài)intend=1;//進程為完成態(tài)intwaiting=2;//進程為等待態(tài)structPCB{intnumber;//進程號intstate;//狀態(tài)intneed;//資源最大需求量intallocation;//資源已占有量intapply;//當前資源申請?zhí)杋ntlapply;//定義進程上次資源申請?zhí)杴P[I];//三個進程structRCB{intR_number;//資源號intR_state;//該資源申請與否}R[N];//10個資源源程序代碼#include"stdio.h"#include"stdlib.h"#include<iostream.h>#include<iomanip.h>#include<time.h>#include<string>usingnamespacestd;#defineI3#defineN10intready=0;//進程為就緒態(tài)intend=1;//進程為完成態(tài)intwaiting=2;//進程為等待態(tài)structPCB{intnumber;//進程號intstate;//狀態(tài)intneed;//資源最大需求量intallocation;//資源已占有量intapply;//當前資源申請?zhí)杋ntlapply;//定義進程上次資源申請?zhí)杴P[I];//三個進程structRCB{intR_number;//資源號intR_state;//該資源申請與否}R[N];//10個資源structPCB*q,*h;structPCB*pr;//用于打印structRCB*r,*k,*s;intNUM[300];intt=0;voidinitialize(intY=0){intm=0,n=0;intt;inta=0;intsuiji;inta1=1,a2=10;cout<<"隨機產(chǎn)生數(shù)據(jù)?(隨機請按1否則按0):";cin>>suiji;if(suiji==1){srand(time(NULL));/*初始化隨機數(shù)種子*/for(q=P;q<P+3;q++)//對進程進行初始化q->need=rand()%(a2-a1)+a1;/*生成一個[1,10)區(qū)間內(nèi)的整數(shù)*/cout<<"進程號"<<setw(20)<<"資源最大需求量"<<endl;for(q=P;q<P+3;q++){a++;cout<<""<<a<<setw(20)<<q->need<<endl;}}else{cout<<"進程號"<<setw(20)<<"資源最大需求量"<<endl;for(q=P;q<P+3;q++){//對進程進行初始化cout<<""<<n<<"";cin>>q->need;while(q->need<1||q->need>10){cout<<"輸入數(shù)據(jù)有誤,請重新輸入:";cin>>q->need;}}}for(q=P;q<P+3;q++){//對進程進行初始化n++;q->number=n;q->state=ready;q->allocation=0;q->apply=0;q->lapply=0;}for(r=R;r<R+10;r++){//對資源進行初始化m++;r->R_number=m;r->R_state=0;}for(t=0;t<300;t++)NUM[t]=0;t=0;}voidpri_num(){intta,a;cout<<endl<<""<<endl;cout<<"******************************************"<<endl;cout<<"進程號:進程1進程2進程3"<<endl;for(ta=0;ta<t-1;t++){cout<<"";for(a=0;a<3;a++){if(NUM[ta]!=0){cout<<setw(11)<<NUM[ta];}elsecout<<"";ta++;}cout<<endl;}cout<<"******************************************"<<endl;}voidpri(){cout<<"****************************************************************************"<<endl;cout<<"進程號"<<setw(8)<<"狀態(tài)"<<setw(15)<<"尚需資源量"<<setw(15)<<"資源最大需求量"<<setw(15)<<"已占資源量"<<setw(15)<<"上次申請資源號"<<endl;cout<<"----------------------------------------------------------------------------"<<endl;for(pr=P;pr<P+3;pr++){cout<<setw(4)<<pr->number<<setw(10);if(pr->state==0)cout<<"就緒";if(pr->state==1)cout<<"完成";if(pr->state==2)cout<<"等待";cout<<setw(10)<<pr->need-pr->allocation<<setw(15)<<pr->need<<setw(15)<<pr->allocation<<setw(15)<<pr->lapply<<endl;cout<<"----------------------------------------------------------------------------"<<endl;}cout<<"****************************************************************************"<<endl;}intCHOICE(intY){//新一輪資源分配選擇函數(shù)cout<<endl<<"****************************************************************************"<<endl;cout<<"現(xiàn)在進入新一輪的資源分配!"<<"1.繼續(xù)"<<"2.退出"<<endl;intchoice;cin>>choice;while(choice<1||choice>2){cout<<"您的輸入有誤!請重新選擇(1/2):";cin>>choice;}switch(choice){case1:Y=1;break;case2:exit(1);}return(Y);}intorder(intY){cout<<endl<<"***************************按序分配算法*************************************"<<endl<<endl;for(q=P-1;;){//控制循環(huán)按照進程1、2、3、1...的順序進行q++;if(q->state==ready){//順序選擇一個就緒進程 if(q->apply==0){//第一次申請資源cout<<endl<<"****請輸入進程"<<q->number<<"當前申請的資源號("<<q->lapply+1<<"--"<<11-(q->need-q->allocation)<<"):";cin>>q->apply;NUM[t]=q->apply;t++;while(q->apply>10||q->apply<1){cout<<"****您的輸入有誤,請重新輸入("<<q->lapply+1<<"--"<<11-(q->need-q->allocation)<<"):";cin>>q->apply;}while((q->need-q->allocation)>(11-q->apply)){t--;cout<<"****有可能產(chǎn)生死鎖,不能滿足您的申請,請重新輸入("<<q->lapply+1<<"--"<<11-(q->need-q->allocation)<<"):";cin>>q->apply;}}else{t++;}r=R+(q->apply)-1;//指向當前申請的資源if(q->apply>=q->lapply){//此時為按序申請if(r->R_state==0){//當前申請的資源沒被占用q->lapply=q->apply;q->apply=0;r->R_state=q->number;q->allocation++; cout<<"****將資源"<<r->R_number<<"分配給了進程"<<q->number<<"!";cout<<"****進程"<<q->number<<"已占用了"<<q->allocation<<"個資源!"<<endl;if(q->allocation==q->need)q->state=end;pri();if(q->allocation==q->need){//當前進程的占有量等于資源最大需求量q->state=end;for(k=R;k<R+10;k++){//進程完成,釋放資源if(k->R_state==q->number)k->R_state=0;}for(h=P;h<P+3;h++){//如果等待的資源被釋放將等待態(tài)的進程改為就緒態(tài)s=R+h->apply-1;if(s->R_state==0){if(h->state==waiting)h->state=ready;}}cout<<"-----------------【進程"<<q->number<<"成功完成分配!!并釋放曾占有的資源】------------------"<<endl<<endl;h=P;if(h->state==end&&(h+1)->state==end&&(h+2)->state==end){cout<<"********************【所有進程都完成,按序算法分配完畢!!!】******************"<<endl;pri_num();CHOICE(Y); return(Y);}else{//進程仍有未完成的循環(huán)if(q==P+2)q=P-1;continue;}}else{//當前進程的占有量小于資源最大需求量if(q==P+2)q=P-1;continue;}}else{//當前申請的資源被占用if(r->R_state==q->number){cout<<"****資源"<<r->R_number<<"已申請,不能重復申請!"<<endl;q->apply=0;}else{cout<<"****資源"<<r->R_number<<"正在被其它進程使用,";cout<<"****進程"<<q->number<<"進入等待態(tài)!"<<endl;q->state=waiting;pri();}if(q==P+2)q=P-1;continue; }}else{//申請未按序cout<<"****沒有按序申請,不能分配!"<<endl;q->apply=0;if(q==P+2)q=P-1;continue;}}else{//該進程不是就緒進程t++;if(q==P+2)q=P-1;continue;//結(jié)束本次循環(huán)}}}intdisorder(intY){cout<<endl<<"*****************************無序分配算法***********************************"<<endl<<endl;for(q=P-1;;){q++;if(q->state==ready){if(q->apply==0){ cout<<endl<<"****請輸入進程"<<q->number<<"當前申請的資源號:"; cin>>q->apply;NUM[t]=q->apply;t++;while(q->apply>10||q->apply<1){t--;cout<<"****您的輸入有誤,請重新輸入:";cin>>q->apply;}r=R+(q->apply)-1;while(r->R_state==q->number){cout<<"****資源"<<r->R_number<<"已申請,不能重復申請!";cout<<"請重新輸入:";cin>>q->apply;t--;NUM[t]=q->apply;t++;r=R+(q->apply)-1;}}else{t++;}r=R+(q->apply)-1;if(r->R_state==0){q->lapply=q->apply;q->a
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 春季防溺水國旗下講話稿(34篇)
- 貨物交付合同范本
- 墓地合同范本模板
- 轉(zhuǎn)正述職報告工作總結(jié)
- 天津駕校 合同范本
- 2023年鎮(zhèn)江市中西醫(yī)結(jié)合醫(yī)院招聘考試真題
- 2023年四川成都中醫(yī)藥大學第二附屬醫(yī)院考核招聘筆試真題
- 2023年麗水市浙拓項目管理有限公司招聘考試真題
- 北京市預付卡合同范本
- 車貼合同范本
- 控制三高健康生活遠離心腦血管疾病課件(模板)
- 光學相干斷層成像(OCT)在冠狀動脈介入診斷與治療中的應用課件
- 模擬法庭案例腳本:校園欺凌侵權(quán)案 社會法治
- 四年級上冊美術教案-14漂亮的房間 |蘇少版
- 05 03 第五章第三節(jié) 投身崇德向善的道德實踐
- 安徽省合肥市第四十五中學2022-2023學年九年級上學期數(shù)學期中考試卷
- 樁基礎工程施工組織方案
- 供水運營管理實施方案(4篇)
- 水土保持工程質(zhì)量評定表
- 水電站基本構(gòu)造原理與類型ppt版(共67)
- 秦朝統(tǒng)一PPT課件教學
評論
0/150
提交評論