LInux實驗 : 程式排程模擬
實驗概述
在作業系統中用c語言實現對N個程式採用動態優先權的程式排程,輸入例項為:
假設在排程前,系統有5個程式,具有如下狀態
5
9 0 3 2 3
38 0 3 1 1
30 0 6 4 2
29 0 3 1 1
0 0 4 1 2
1
每個標示程式的程式控制看PCB用結構體來描述,包括程式id,程式優先順序priority,越大優先順序別越高,已佔用CPU時間cputime,還需佔用CPU時間alltime,程式阻塞時間starblock,程式被阻塞時間blocktime,基礎狀態state
預設輸出程式排程式列的id,以空格分隔,當輸入的最後一行為1時,輸出每一步的系統狀態。
優先數改變的原則:程式在就緒佇列中呆一個時間片,優先數增加1,程式每執行一個時間片優先數減3。
實驗內容
結構PCB
首先使用結構PCB來描述程式,
struct PCB
{
int ID;//程式id
int PRIORITY;//程式優先順序,越大越優先
int CPUTIME;//已經執行的時間片
int ALLTIME;//還要執行的時間片
int STARTBLOCK;//程式開始變成BLCOK的時間片
int BLOCKTIME;//經過BLCOKTIME之後程式由BLOCK轉變成READY
int STATE;//程式的狀態READY--1,BLOCK--2
PCB *next;//指向下一個程式
};
除卻上述講到的程式id,程式優先順序priority,越大優先順序別越高,已佔用CPU時間cputime,還需佔用CPU時間alltime,程式阻塞時間starblock,程式被阻塞時間blocktime,基礎狀態state等屬性之外,還需增加一個指向下一個程式的指標。
動態優先數是指在程式建立時先確定一個初始優先數, 以後在程式執行中隨著程式特性的改變不斷修改優先數,這樣,由於開始優先數很低而得不到CPU的程式,就能因為等待時間的增長而優先數變為最高而得到CPU執行。
因此,為了排程方便,初始化就緒佇列,阻塞佇列和CPU之後,先把給定的程式從大到小連成佇列,包含頭節點,用指標給出佇列的連線情況。若佇列不為空,就緒佇列首程式就開始投入執行,時間片執行完成,程式已佔有的CPU時間+1,當執行程式已佔用的時間達到所需要的執行時間時進行判斷,若程式完成則促銷改程式,若還未完成就將該執行程式的優先數-1.並把該執行程式插入到就緒佇列中去。再根據優先數改變的原則,程式在就緒佇列中呆一個時間片,優先數增加1,程式每執行一個時間片優先數減3,排程程式狀態並顯示。
重要函式程式碼
1.排程演算法
void MyDispatcher()
{
if(!Is_CPU_Busy)//CPU空閒
{
Running_p=GetFirstProcess(Ready_Queue_Head);//獲取就緒佇列優先順序最高的程式
}
else//CPU不空閒
{
if(!Is_Empty_Queue(Ready_Queue_Head) && Ready_Queue_Head->next->PRIORITY>Running_p->PRIORITY)//如果就緒佇列的程式中存在優先順序比running process的優先順序大就應該搶佔CPU
{
InsetProcess(Running_p,Ready_Queue_Head);//把執行中的程式進隊
Running_p=GetFirstProcess(Ready_Queue_Head);//把running_p設為最新的優先順序最大的程式
}
}
}
2.CPU函式
void CPUWork()
{
Is_CPU_Busy=true;
//執行Running_p......
Cur_Time++;
Running_p->ALLTIME--;
Running_p->CPUTIME++;
Running_p->PRIORITY-=3;
Update_Ready_Queue();
Update_Block_Queue();
if(Running_p->BLOCKTIME>0 && Running_p->STARTBLOCK==Running_p->CPUTIME)//如果程式阻塞了
{
Running_p->STATE=BLOCK;
InsetProcess(Running_p,Block_Queue_Head);
Is_CPU_Busy=false;
MyDispatcher();
Is_CPU_Busy=true;
}
if(Running_p->ALLTIME==0)//如果程式順利完結
{
Is_CPU_Busy=false;
MyDispatcher();
Is_CPU_Busy=true;
}
}
3.佇列更新函式:
void Update_Block_Queue()
{
PCB *p=Block_Queue_Head->next;
PCB *p_before=Block_Queue_Head;
while(p!=NULL)
{
//p->PRIORITY++;
p->BLOCKTIME--;
if(p->BLOCKTIME==0)//變回就緒狀態
{
p_before->next=p->next;//把該程式從阻塞佇列中刪去
p->STATE=READY;
InsetProcess(p,Ready_Queue_Head);//把改程式插回就緒佇列
p=p_before->next;
}
else
{
p_before=p;
p=p->next;
}
}
主要程式碼分析
輸入PCB資訊,即保證CPU,就緒佇列和阻塞佇列中的程式數不為0。
1.先判斷CPU是否空閒。CPU空閒的話,從就緒佇列中選取優先順序最大的;而如果就緒佇列為空,則從阻塞佇列中選取第一個程式。選中的程式的cputime設定為0。CPU上有程式的話,就更新CPU上程式的狀態,列印CPU上程式的id。如果CPU上的程式的alltime已經為0,即程式已經完成了,更新該程式的狀態為finish,將CPU清空。如果程式在CPU上的時間達到starttime,將其放到阻塞佇列,清空CPU。
2.更新阻塞佇列和就緒佇列中的程式中的狀態,列印就緒佇列和阻塞佇列的程式的id。
3.列印每個程式的狀態。
迴圈操作直至CPU,就緒佇列和阻塞佇列中都沒有程式為止。
程式碼最終執行結果截圖(前2個時間片和第18個時間片):
相關文章
- linux程式排程Linux
- Linux程式排程邏輯與原始碼分析Linux原始碼
- 排程器簡介,以及Linux的排程策略Linux
- Linux IO排程方法Linux
- Cisco Packet Tracer NAT模擬實驗
- Linux核心學習筆記(5)– 程式排程概述Linux筆記
- OS_程式排程:C++實現C++
- linux搶佔式排程Linux
- Linux I/O排程器Linux
- 分割槽儲存管理模擬實驗
- Linux 定時任務排程Linux
- Python任務排程模組APSchedulerPython
- Linux中什麼情況下會發生程式排程?Linux
- linux中設定程式排程的優先順序別Linux
- haipproxy核心校驗和排程策略AI
- Flink排程之排程器、排程策略、排程模式模式
- Linux程序排程器-CPU負載Linux負載
- Linux Shell指令碼時間排程Linux指令碼
- 使用lua-nginx模組實現請求解析與排程Nginx
- 實戰Docker容器排程Docker
- 100行程式碼實現React核心排程功能行程React
- 程式排程案例分析與常見疑惑1:為何不能排程?
- Nachos實驗實現執行緒id、限制執行緒數和更改排程演算法(按優先順序排程)執行緒演算法
- 增補部落格 第十七篇 python 模擬頁面排程LRU演算法Python演算法
- Linux排程器:程序優先順序Linux
- linux之 修改磁碟排程演算法Linux演算法
- 如何更改Linux的I/O排程器Linux
- linux模擬windows嘗試LinuxWindows
- Kubernetes 排程器實現初探
- 程式碼模擬重慶高考平行志願錄取過程
- 基於CVX凸最佳化的電動汽車充放電排程matlab模擬Matlab
- Linux 中 Laravel 任務排程不執行LinuxLaravel
- 整合運放線性區運用的模擬實驗
- ECU通訊:CAN匯流排模擬測試
- 模擬銀行排隊時間—4佇列佇列
- 關於 Linux 中模擬滑鼠Linux
- 小車側方位停車過程的動態模擬matlab模擬Matlab
- Go 併發程式設計 - runtime 協程排程(三)Go程式設計