目錄
前言
二、實驗目的
三、實驗要求
四、實驗原理
五、實驗過程
六、代碼詳解
總結
前言
計算機操作系統(tǒng)是管理計算機硬件和軟件資源的核心軟件,它負責為用戶提供一個友好、高效、安全的使用環(huán)境。進程調度是操作系統(tǒng)的一個重要功能,它決定了進程在處理器上的執(zhí)行順序和時間,從而影響了系統(tǒng)的性能和用戶的體驗。本實驗旨在通過模擬不同的進程調度算法,比較它們的優(yōu)缺點,加深對操作系統(tǒng)原理和設計的理解和掌握。
一、開發(fā)語言及實驗平臺
C++/JAVA
Turbo C / Microsoft Visual Studio 6.0 / Microsoft Visual Studio .NET 2010
在本文中使用的是c語言(?),使用的平臺是devc++
二、實驗目的
(1)加深對進程的概念及進程調度算法的理解;
(2)在了解和掌握進程調度算法的基礎上,編制進程調度算法通用程序,將調試結果顯示在計算機屏幕上,并檢測機算和筆算的一致性。
三、實驗要求
(1)了解進程調度;
(2)理解利用進程調度算法進行調度的原理;
(3)使用某種編程語言進行算法模擬。
四、實驗原理
- 例題:設計一個有N個進程的進程調度算法。
進程調度算法:采用最高優(yōu)先數(shù)的調度算法(即把處理機分配給優(yōu)先數(shù)最高的進程)。
每個進程有一個進程控制塊(PCB)表示。進程控制塊可以包含如下信息:進程名、優(yōu)先數(shù)、到達時間、需要運行時間、已用CPU時間、進程狀態(tài)等等。
進程的優(yōu)先數(shù)及需要的運行時間可以事先人為的指定(也可以由隨機數(shù)產生)。進程的到達時間為進程的輸入的時間。進程的運行時間以時間片為單位進行計算。
每個進程的狀態(tài)可以是就緒W(Wait)、運行R(Run)、或完成F(Finish)三種狀態(tài)之一。就緒進程獲得CPU后都只能運行一個時間片。用已占用CPU時間加1表示。
如果運行一個時間片后,進程的已占用CPU時間已達到所需要的運行時間,則撤銷該進程,如果運行一個時間片后,進程的已占用CPU時間還未達到所需要的運行時間,也就是進程還需要繼續(xù)運行,此時應該將進程的優(yōu)先數(shù)減1(即降低一級),然后把它插入就緒隊列等待CPU。
每進行一次調度程序都打印一次運行進程、就緒隊列、以及各個進程的PCB,以便進行檢查。
重復以上過程,直到所要的進程都完成為止。
分析:
使用固定隊列與靜動態(tài)優(yōu)先級結合,每個優(yōu)先級為0~0xFF,并且以小的數(shù)字為高優(yōu)先級,大的數(shù)字為低優(yōu)先級,每次皆使用循環(huán)得到最高優(yōu)先級的進程并執(zhí)行,然后將其動態(tài)優(yōu)先級設置為最低,并將其他進程動態(tài)優(yōu)先級提高,以使得每個進程都有機會運行。進程的優(yōu)先級與運行時間由隨機數(shù)產生。
五、實驗過程
代碼如下:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
/*常量和狀態(tài)定義*/
#define PRO_NUM 0x05
#define MAX_TIME 0xFF
/*狀態(tài)宏*/
#define WAIT 0x01
#define RUN 0x02
#define FINISH 0x03
#define ID_ERROR 0x10
#define MIN_PRIOR 0xFF //255
#define MAX_PRIOR 0x00 0
typedef unsigned int Uint32;
/*進程PCB*/
struct PCB_Info
{
Uint32 s_id;
Uint32 s_static_prior;
Uint32 s_dynamic_prior;
Uint32 s_start_time;
Uint32 s_need_time;
Uint32 s_used_time;
Uint32 s_state;
};
/*進程隊列*/
PCB_Info g_queue[5];
Uint32 g_time = 0;
/*模擬進程執(zhí)行函數(shù)*/
void Simulator();
/*初始化5個進程函數(shù)*/
void Init_Process();
/*初始化進程隊列函數(shù)*/
void Init_Queue();
/*創(chuàng)建進程函數(shù)*/
Uint32 Create_Process(Uint32 pri,Uint32 needtime);
/*系統(tǒng)運行函數(shù)*/
void Run_Process();
/*得到最高優(yōu)先級進程 ID函數(shù)*/
Uint32 Get_PriProcess();
/*進程時間片執(zhí)行函數(shù)*/
void Work_Process(Uint32 id);
/*改變進程狀態(tài)和優(yōu)先級函數(shù)*/
void Change_Process(Uint32 id);
/*打印進程狀態(tài)函數(shù)*/
void Print_State();
/*結束系統(tǒng)函數(shù)*/
void End_Process();
/*入口函數(shù)*/
int main( int argc, char *argv[ ])
{
Simulator();
return 0;
}
void Simulator()
{
Init_Process();
Run_Process();
End_Process();
}
void Init_Process()
{
int i;
Uint32 id;
srand( (unsigned)time( NULL ) );
Init_Queue();
for(i=0;i<PRO_NUM;++i)
{
/*在這里修改隨機數(shù)的范圍,建議優(yōu)先級取值為0到4之間,進程工作總時間為1到10之間*/
id=Create_Process(rand()%5, 1+rand()%10);
if(id!=ID_ERROR)
{
printf("**********************************\n");
printf("創(chuàng)建進程成功\n");
printf("進程ID號為:%d\n",id);
printf("進程的靜態(tài)優(yōu)先權為:%d\n",g_queue[id].s_static_prior);
printf("進程的動態(tài)優(yōu)先權為:%d\n",g_queue[id].s_dynamic_prior);
printf("進程的到達時間為:%d\n",g_queue[id].s_start_time);
printf("進程需要時間為:%d\n",g_queue[id].s_need_time);
printf("進程已用CPU時間為:%d\n",g_queue[id].s_used_time);
printf("進程的狀態(tài)為:%d\n",g_queue[id].s_state);
printf("\n");
}
else
{
printf("創(chuàng)建進程失敗\n");
}
}
}
void Init_Queue()
{
int i;
for(i=0;i<PRO_NUM;++i)
{
g_queue[i].s_id=i;
g_queue[i].s_dynamic_prior=MIN_PRIOR; //255
g_queue[i].s_need_time=0;
g_queue[i].s_start_time=0;
g_queue[i].s_static_prior=MIN_PRIOR;
g_queue[i].s_used_time=0;
g_queue[i].s_state=FINISH;
//g_queue[i].s_state=Sart;//這里有一個錯誤,在這里Sart并沒有被定義,根據(jù)上下文,這里應該是想將進程的狀態(tài)設置為START或者WAIT,根據(jù)上面的宏定義,將這里改成WAIT
}
}
Uint32 Create_Process(Uint32 pri,Uint32 needtime)
{
int i=0;
Uint32 id=ID_ERROR;
for(i=0;i<PRO_NUM;++i)
{
if(g_queue[i].s_state ==FINISH)
{
id=g_queue[i].s_id;
g_queue[i].s_dynamic_prior=MIN_PRIOR;
g_queue[i].s_need_time=needtime;
g_queue[i].s_start_time=g_time;
g_queue[i].s_state=WAIT;
g_queue[i].s_static_prior=pri;
g_queue[i].s_used_time=0x0;
break;
}
}
return id;
}
void Run_Process()
{
Uint32 id;
while((id=Get_PriProcess())!=ID_ERROR)
{
Work_Process(id);
Change_Process(id);
}
}
void Print_State()
{
int i;
printf("時間 進程ID\t狀態(tài) 已用時間 需要時間 開始時間 靜優(yōu)先級 動優(yōu)先級\n");
for(i=0;i<PRO_NUM;++i)
{
printf("%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n",g_time,g_queue[i].s_id,g_queue[i].s_state,g_queue[i].s_used_time,g_queue[i].s_need_time,
g_queue[i].s_start_time,g_queue[i].s_static_prior,g_queue[i].s_dynamic_prior);
}
}
Uint32 Get_PriProcess()
{
Uint32 id=ID_ERROR;
int i, prev_id=ID_ERROR;
Uint32 prior=MIN_PRIOR*2, temp_prior;
for(i=0;i<PRO_NUM;++i)
{
if(g_queue[i].s_state!=FINISH)
{
temp_prior=g_queue[i].s_dynamic_prior+g_queue[i].s_static_prior;
if(temp_prior<=prior)
{
id=i;
prior=temp_prior;
}
}
}
return id;
}
void Work_Process(Uint32 id)
{
++g_time;
g_queue[id].s_state=RUN;
++g_queue[id].s_used_time;
Print_State();
}
void Change_Process(Uint32 id)
{
int i;
if(g_queue[id].s_need_time==g_queue[id].s_used_time)
{
g_queue[id].s_state=FINISH;
}
else
{
g_queue[id].s_dynamic_prior=MIN_PRIOR;
g_queue[id].s_state=WAIT;
}
for(i=0;i<PRO_NUM;++i)
{
if((i!=id)&&(g_queue[i].s_state!=FINISH))
{
g_queue[i].s_dynamic_prior >0 ?--g_queue[i].s_dynamic_prior:g_queue[i].s_dynamic_prior=0;
}
}
}
void End_Process()
{
printf("所有進程結束狀態(tài):\n");
Print_State();
printf("所有進程已經結束!\n");
}
六、代碼詳解
這是一段C語言的進程調度程序,現(xiàn)在來解釋一下這段代碼:
這段代碼是一個簡單的進程調度程序,它使用優(yōu)先級調度算法來模擬進程的執(zhí)行。程序中定義了一些常量和狀態(tài),包括進程數(shù)量、最大時間、等待狀態(tài)、運行狀態(tài)和完成狀態(tài)。它還定義了一個PCB_Info結構體,用來表示進程的PCB(進程控制塊),其中包含了進程的ID、靜態(tài)優(yōu)先級、動態(tài)優(yōu)先級、開始時間、需要時間、已使用時間和狀態(tài)。
代碼中還定義了一個全局變量g_queue,用來表示進程隊列,以及一個全局變量g_time,用來表示當前時間。此外,還定義了一些函數(shù)原型,包括模擬進程執(zhí)行函數(shù)Simulator(),初始化5個進程函數(shù)Init_Process(),初始化進程隊列函數(shù)Init_Queue(),創(chuàng)建進程函數(shù)Create_Process(),系統(tǒng)運行函數(shù)Run_Process(),得到最高優(yōu)先級進程ID函數(shù)Get_PriProcess(),進程時間片執(zhí)行函數(shù)Work_Process(),改變進程狀態(tài)和優(yōu)先級函數(shù)Change_Process(),打印進程狀態(tài)函數(shù)Print_State()和結束系統(tǒng)函數(shù)End_Process()。
在main()函數(shù)中調用了Simulator()函數(shù)來模擬整個系統(tǒng)的運行。Simulator()函數(shù)中依次調用了Init_Process()函數(shù)來初始化5個進程,Run_Process()函數(shù)來運行系統(tǒng),并在最后調用End_Process()函數(shù)來結束系統(tǒng)。
Init_Process()函數(shù)用來初始化5個進程。在這個函數(shù)中,首先調用了Init_Queue()函數(shù)來初始化進程隊列,然后使用for循環(huán)來創(chuàng)建5個進程。在循環(huán)中,使用rand()函數(shù)來生成隨機數(shù),作為創(chuàng)建進程的優(yōu)先級和需要時間的參數(shù)。然后調用Create_Process()函數(shù)來創(chuàng)建進程,并根據(jù)返回值判斷是否創(chuàng)建成功。如果創(chuàng)建成功,則打印出進程的相關信息;否則,打印出創(chuàng)建失敗的信息。
Init_Queue()函數(shù)用來初始化進程隊列。在這個函數(shù)中,使用for循環(huán)來遍歷進程隊列中的每一個元素,并對其進行初始化。初始化包括設置進程的ID、動態(tài)優(yōu)先級、需要時間、開始時間、靜態(tài)優(yōu)先級、已使用時間和狀態(tài)。
Create_Process()函數(shù)用來創(chuàng)建進程。在這個函數(shù)中,首先遍歷進程隊列,尋找一個狀態(tài)為FINISH的進程。如果找到了,則將其ID賦值給id變量,并對其進行初始化,包括設置動態(tài)優(yōu)先級、需要時間、開始時間、狀態(tài)、靜態(tài)優(yōu)先級和已使用時間。最后返回id變量的值。
Run_Process()函數(shù)用來運行系統(tǒng)。在這個函數(shù)中,首先調用Get_PriProcess()函數(shù)來獲取最高優(yōu)先級的進程ID。如果返回值不等于ID_ERROR,則調用Work_Process()函數(shù)來執(zhí)行該進程,并調用Change_Process()函數(shù)來改變該進程的狀態(tài)和優(yōu)先級。然后繼續(xù)循環(huán),直到Get_PriProcess()函數(shù)返回ID_ERROR為止。
Get_PriProcess()函數(shù)用來獲取最高優(yōu)先級的進程ID。在這個函數(shù)中,首先定義了一個id變量并初始化為ID_ERROR,然后使用for循環(huán)來遍歷進程隊列中的每一個元素。對于每一個元素,如果它的狀態(tài)不為FINISH,則計算它的優(yōu)先級(靜態(tài)優(yōu)先級+動態(tài)優(yōu)先級),并與當前最高優(yōu)先級進行比較。如果它的優(yōu)先級小于等于當前最高優(yōu)先級,則更新id變量和當前最高優(yōu)先級。最后返回id變量的值。
Work_Process()函數(shù)用來執(zhí)行進程。在這個函數(shù)中,首先將全局變量g_time加1,然后將指定進程的狀態(tài)設置為RUN,并將其已使用時間加1。最后調用Print_State()函數(shù)來打印進程狀態(tài)。
Change_Process()函數(shù)用來改變進程狀態(tài)和優(yōu)先級。在這個函數(shù)中,首先判斷指定進程是否已經完成(即已使用時間等于需要時間)。如果已經完成,則將其狀態(tài)設置為FINISH;否則,將其動態(tài)優(yōu)先級設置為MIN_PRIOR,并將其狀態(tài)設置為WAIT。然后使用for循環(huán)來遍歷進程隊列中的其他元素,并對它們的動態(tài)優(yōu)先級進行更新。
End_Process()函數(shù)用來結束系統(tǒng)。在這個函數(shù)中,首先打印出所有進程結束狀態(tài)的信息,然后調用Print_State()函數(shù)來打印進程狀態(tài)。最后打印出所有進程已經結束的信息。
效果如下:
?以上。
總結
本實驗通過編寫一個C語言的進程調度程序,來模擬優(yōu)先級調度算法的過程和效果。程序中定義了進程的PCB結構體,包含了進程的ID、靜態(tài)優(yōu)先級、動態(tài)優(yōu)先級、開始時間、需要時間、已使用時間和狀態(tài)等信息。程序還定義了一些函數(shù),用來初始化進程隊列、創(chuàng)建進程、運行系統(tǒng)、獲取最高優(yōu)先級進程、執(zhí)行進程、改變進程狀態(tài)和優(yōu)先級、打印進程狀態(tài)和結束系統(tǒng)等功能。程序使用了隨機數(shù)來生成進程的優(yōu)先級和需要時間,并使用循環(huán)來遍歷進程隊列,找到最高優(yōu)先級的進程并執(zhí)行,然后降低其動態(tài)優(yōu)先級,并提高其他進程的動態(tài)優(yōu)先級,以保證每個進程都有機會運行。程序在每次執(zhí)行一個進程后,都會打印出當前的時間和所有進程的狀態(tài),以便觀察和檢查。程序在所有進程都完成后,會打印出最終的結果,并結束系統(tǒng)。文章來源:http://www.zghlxwxcb.cn/news/detail-468736.html
通過本實驗,加深了對進程調度算法的理解和掌握,熟悉了C語言的編程技巧和調試方法,提高了分析問題和解決問題的能力。文章來源地址http://www.zghlxwxcb.cn/news/detail-468736.html
到了這里,關于計算機操作系統(tǒng)實驗:進程調度實驗的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!