【操作系統】實驗三 進程調度模擬程序


實驗三 進程調度模擬程序

1.    目的和要求

1.1.           實驗目的

用高級語言完成一個進程調度程序,以加深對進程的概念及進程調度算法的理解。

1.2.           實驗要求

1.2.1例題:設計一個有 N個進程並發執行的進程調度模擬程序。

進程調度算法:采用最高優先級優先的調度算法(即把處理機分配給優先級最高的進程)和先來先服務(若優先級相同)算法。

(1).  每個進程有一個進程控制塊(PCB)表示。進程控制塊包含如下信息:進程名、優先級、到達時間、需要運行時間、已用CPU時間、進程狀態等等。

(2).  進程的優先級及需要的運行時間可以事先人為地指定,進程的運行時間以時間片為單位進行計算。

(3).  每個進程的狀態可以是就緒 r(ready)、運行R(Running)、或完成F(Finished)三種狀態之一。

(4).  就緒進程獲得 CPU后都只能運行一個時間片。用已占用CPU時間加1來表示。

(5).  如果運行一個時間片后,進程的已占用 CPU時間已達到所需要的運行時間,則撤消該進程,如果運行一個時間片后進程的已占用CPU時間還未達所需要的運行時間,也就是進程還需要繼續運行,此時應將進程的優先數減1(即降低一級),然后把它插入就緒隊列等待調度。

(6).  每進行一次調度程序都打印一次運行進程、就緒隊列中各個進程的 PCB,以便進行檢查。   

(7).  重復以上過程,直到所要進程都完成為止。

思考:作業調度與進程調度的不同?

1.2.2實驗題A:編寫並調試一個模擬的進程調度程序,采用“最高優先數優先”調度算法對N(N不小於5)個進程進行調度。

“最高優先級優先”調度算法的基本思想是把CPU分配給就緒隊列中優先數最高的進程。

(1). 靜態優先數是在創建進程時確定的,並在整個進程運行期間不再改變。

(2). 動態優先數是指進程的優先數在創建進程時可以給定一個初始值,並且可以按一定規則修改優先數。例如:在進程獲得一次CPU后就將其優先數減少1,並且進程等待的時間超過某一時限(2個時間片時間)時增加其優先數等。

(3). (**)進程的優先數及需要的運行時間可以事先人為地指定,(也可以由隨機數產生)。

(4). (**)在進行模擬調度過程可以創建(增加)進程,其到達時間為進程輸入的時間。

0.

 

1.2.3實驗題B:編寫並調試一個模擬的進程調度程序,采用“基於時間片輪轉法”調度算法對N(N不小於5)個進程進行調度。 “輪轉法”有簡單輪轉法、多級反饋隊列調度算法。

(1). 簡單輪轉法的基本思想是:所有就緒進程按 FCFS排成一個隊列,總是把處理機分配給隊首的進程,各進程占用CPU的時間片長度相同。如果運行進程用完它的時間片后還未完成,就把它送回到就緒隊列的末尾,把處理機重新分配給隊首的進程。直至所有的進程運行完畢。(此調度算法是否有優先級?)

 (2). 多級反饋隊列調度算法的基本思想是:

將就緒隊列分為N級(N=3~5),每個就緒隊列優先數不同並且分配給不同的時間片:隊列級別越高,優先數越低,時間片越長;級別越小,優先數越高,時間片越短。

系統從第一級調度,當第一級為空時,系統轉向第二級隊列,.....當處於運行態的進程用完一個時間片,若未完成則放棄CPU,進入下一級隊列。

當進程第一次就緒時,進入第一級隊列。

(3). (**)考慮進程的阻塞狀態B(Blocked)增加阻塞隊列。進程的是否阻塞和阻塞的時間由產生的“隨機數”確定(阻塞的頻率和時間長度要較為合理)。注意進程只有處於運行狀態才可能轉換成阻塞狀態,進程只有處於就緒狀態才可以轉換成運行狀態。

 

2.    實驗內容

根據指定的實驗課題:A(1),A(2),B(1)和B(2)

完成設計、編碼和調試工作,完成實驗報告。

注:帶**號的條目表示選做內容。

 

3.    實驗環境

可以選用Turbo C作為開發環境。也可以選用Windows下的VB,CB等可視化環境,利用各種控件較為方便。自主選擇實驗環境。

4.    實驗原理及核心算法參考程序段

     動態優先數(優先數只減不加):

#include<stdio.h>
#include<string.h>
#include<time.h>
#define N 3
typedef struct jcb{
    char name[10];//進程名
    int reqtime;//要求服務時間
    int prio;//優先級
    int runtime;//運行時間 
    char status;
}PCB;
int intarr=0,intfin=0;//到達進程個數,完成進程個數
PCB pcbarr[24],pcbfin[24];

void Mune()
{
    printf("\n\n");
    printf("\t\t|------------------------------------------------|\n");
    printf("\t\t|                 進程調度模擬程序               |\n");
    printf("\t\t|------------------------------------------------|\n");
    printf("\t\t|       0:退出                                   |\n");
    printf("\t\t|       1:運行(最高優先級優先算法)             |\n");
    printf("\t\t|       2:插入                                   |\n");
    printf("\t\t|       3:刪除                                   |\n");
    printf("\t\t|------------------------------------------------|\n");
    printf("請選擇<0~3>:");
}
void Input()//手動輸入
{
    int i;
    int n=0;
    printf("請輸入進程個數:");
    scanf("%d",&n);
    for(i=0;i<n;i++,intarr++)
    {
        printf("\n第%d個進程:\n請輸入進程名:",i+1);
        scanf("%s",pcbarr[intarr].name);
        printf("請輸入要求服務時間:");
        scanf("%d",&pcbarr[intarr].reqtime);
        pcbarr[intarr].prio=N;//優先級為3
        if(i==0)
            pcbarr[intarr].status='r';
        else
            pcbarr[intarr].status='w';
    }
}

void Output()//輸出排序后隊列
{
    int i=0;
    printf("\n\n運行隊列的是\n");
    printf("\tname\treqtime\truntime\tprio\tstatus\n");
    if(intarr!=0){
    printf("N%d\t%s\t%d\t%d\t%d\t%c\n",i,pcbarr[i].name,pcbarr[i].reqtime,pcbarr[i].runtime,pcbarr[i].prio,pcbarr[i].status);
    }
    printf("\n就緒隊列的是\n");
    printf("\tname\treqtime\truntime\tprio\tstatus\n");
    for(i=1;i<intarr;i++){
        printf("N%d\t%s\t%d\t%d\t%d\t%c\n",i,pcbarr[i].name,pcbarr[i].reqtime,pcbarr[i].runtime,pcbarr[i].prio,pcbarr[i].status);
    }
    printf("\n已完成隊列的是\n");
    printf("\tname\treqtime\truntime\tprio\tstatus\n");
    for(i=0;i<intfin;i++){
        printf("N%d\t%s\t%d\t%d\t%d\t%c\n",i,pcbfin[i].name,pcbfin[i].reqtime,pcbfin[i].runtime,pcbfin[i].prio,pcbfin[i].status);
    }
    printf("\n*********************************************\n");
}

//按優先級排序
void Sort()
{
    int i,j;
    PCB temp;
    for(i=0;i<intarr-1;i++)
    {
        for(j=i+1;j<intarr;j++)
        {
            if(pcbarr[i].prio<pcbarr[j].prio)
            {
                temp=pcbarr[i];
                pcbarr[i]=pcbarr[j];
                pcbarr[j]=temp;
            }
        }
    }
    pcbarr[0].status='r'; 
    for(i=1;i<intarr;i++)
    {
        pcbarr[i].status='w';
    }
}
void running()
{ 
  int slice,i,k;
  slice=1;

  for(i=1;i<((N+1)-pcbarr[0].prio);i++)
    slice=slice*2;
    
  for(i=1;i<=slice;i++)
  {
     pcbarr[0].runtime++; 
     if (pcbarr[0].runtime==pcbarr[0].reqtime)
       break;
       
  }
  if(pcbarr[0].runtime==pcbarr[0].reqtime) 
  {
      printf("\n 進程 [%s] 已完成.\n",pcbarr[0].name); 
      pcbfin[intfin]=pcbarr[0];
      for(k=0;k<=intarr;k++)
      {
        pcbarr[k]=pcbarr[k+1];
      }
      intarr--;
      intfin++;
  }
  else 
  { 
    if(pcbarr[0].prio>1) pcbarr[0].prio--; 

  } 
} 

void Delete()
{
    char b[20];
    int i,j,key=0;
    printf("請輸入要刪除的進程名:");
    scanf("%s",b);
    for(i=0;i<intarr;i++)
    {
        if(strcmp(b,pcbarr[i].name)==0)
         {
            key=1;
            for(j=i;j<=intarr;j++)
            {
                  pcbarr[j]=pcbarr[j+1];

            }    
            intarr--;
         }
     }
     for(i=0;i<intfin;i++)
    {
        if(strcmp(b,pcbfin[i].name)==0)
        {
            key=1;
            for(j=i;j<=intfin;j++)
            {
                pcbfin[j]=pcbfin[j+1];

            }
            intfin--;
        }
    }
       if(key==0)
       {
           printf("查找不到該進程!");
       }
}
main()
{
    int chose;
    Input();
    Output();
    while(1)
    {
        Mune();
        scanf("%d",&chose);
        switch(chose)
        {
        case 0:exit(0);break;
        case 1:running();break;
        case 2:Input();break;
        case 3:Delete();break;
        default:printf("輸入錯誤!");
        }
        Sort(); 
        Output();
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM