行程控制
基本要求
模擬作業系統內核對行程的控制和管理:包括行程的創建和撤銷、行程狀態的切換和簡單的記憶體空間管理,
實驗提示
1、 定義管理每個行程的資料結構PCB:包含行程名稱、佇列指標、分配的物理記憶體區域(基址和長度),每創建一個行程時,需要為其創建PCB并分配空閑記憶體空間,對PCB進行初始化,并加入就緒佇列,(斜體為可選)
可參考如下資料結構(動態形式):
|
struct PCB{ char name[8]; struct PCB *next; ... }; struct PCB *ready,*blocked,*running; |
創建行程時申請空白PCB:
|
struct PCB *p=(struct PCB *)malloc(sizeof(struct PCB)); |
并把新建行程的PCB添加到就緒佇列末尾:
|
add(ready,p); |
其中,ready為就緒佇列頭節點,并在開始處分配了空間;add函式是鏈表中添加節點函式,代碼參考如下:
void add(struct PCB *head, struct PCB *process){ struct PCB *tmp=head; while(tmp->next!=NULL) tmp=tmp->next; tmp->next=process; process->next=NULL; }
2、 模擬觸發行程狀態轉換的事件:采用鍵盤控制方法來模擬觸發行程狀態切換的事件(例如輸入1代表創建新行程、2執行行程時間片到、3阻塞執行行程、4喚醒第一個阻塞行程、5終止執行行程),實作對應的控制程式,
3、 根據當前發生的事件對行程的狀態進行切換,并顯示出當前系統中的執行佇列、就緒佇列和阻塞佇列,
4、 *(選做)完成可變磁區的分配與回收,創建行程的同時申請一塊連續的記憶體空間,在PCB中設定好基址和長度,結束行程時回收分配的記憶體空間,分配可采用首次適應、最佳適應或最差適應演算法,碎片大小為2Kb,最后回收所有行程的空間,對空間磁區的合并,可以查看行程所占的空間和系統空閑空間,
可以用一個鏈表(如圖1-1所示)來維護已分配的和空閑的記憶體段,其中一個段或者包含一個行程,或者是兩個行程之間的空閑段, 在圖1-1中,鏈表的每一項包含四個值域,第一個值域表示記憶體段是空閑或占用(例如,空閑段用H表示,行程占用的段用P表示);第二個值域表示記憶體段的起始位置,第三個值域表示記憶體段的長度;第四個值域為指向鏈表下一項的指標,該鏈表按照記憶體段的起始地址進行從小到大排序,這樣排序的好處是方便記憶體空間的回收,一個要終止的行程一般會有兩個鄰居(除了在記憶體頂端和記憶體底端的行程),鄰居可能是行程也可能是空閑段,根據兩個鄰居的不同型別,可以分為四種回收情況(如圖1-2所示),在圖1-2(a)中,對鏈表的更新只需要將P置為H;在圖1-2(b)和(c)中,需要將P置為H,并將該項與另外一個相鄰的空閑段的項合并為一項;在圖1-2(d)中,需要將該項和兩個鄰居合并為一項,考慮到合并空閑段需要查看鄰居,因此用雙向鏈表會比單向鏈表更加方便,

圖 1-1. (a) 記憶體空間的示例,有5個行程和3個空閑段,陰影部分表示空閑段,
(b) 管理記憶體空間的鏈表

圖 1-2. 對終止的行程X的四種記憶體回收情況(陰影代表空閑區)
實驗代碼
#include<iostream> #include<stdlib.h> #include<string.h> using namespace std; struct PCB{ char name[8]; struct PCB *next; }; struct PCB *ready,*blocked,*running; struct PCB *p=(struct PCB *)malloc(sizeof(struct PCB)); //插入佇列 void add(struct PCB *head,struct PCB *process){ struct PCB *tmp=head; while(tmp->next!=NULL) tmp=tmp->next; tmp->next=process; process->next=NULL; } //出佇列 struct PCB *movefirst(struct PCB *head){ struct PCB *tmp=head->next; if(tmp!=NULL) { head->next=tmp->next; tmp->next=NULL; } return tmp; }; //創建行程 void creat() { struct PCB *tmp; char name[10]; cout<<"輸入行程名字:"; cin>>name; tmp=(struct PCB*)malloc(sizeof(struct PCB)); strcpy(tmp->name,name); //字串復制函式 tmp->next=NULL; add(ready,tmp); if(running==NULL) //如果當前沒有正在執行的行程就將新創建的行程運行 running=movefirst(ready); } //時間片到 void timeout(){ if(ready->next==NULL) // 容錯處理 cout<<"\t\t就緒佇列為空!"<<endl; if(running!=NULL) { add(ready,running); running=movefirst(ready); } else running=movefirst(ready); } //阻塞行程 void block(){ if(running!=NULL) { add(blocked,running); running=movefirst(ready); } else cout<<"\t\t沒有運行的行程,無法阻塞!"<<endl; } //喚醒行程 void wakeup(){ if (blocked->next == NULL){ printf("阻塞態已為空!!!\n"); } else{ struct PCB *T = (struct PCB*)malloc(sizeof(struct PCB)); T = movefirst(blocked); add(ready,T); if (running == NULL){ running =movefirst(ready); } } } //終止行程 void stop(){ if(running!=NULL) { free(running); running=movefirst(ready); } else cout<<"\t\t沒有運行的行程"<<endl; } //展示 void show() { struct PCB *tmp; cout<<endl; cout<<"執行佇列:"; if(running!=NULL) cout<<" "<<running->name; cout<<endl; cout<<"就緒佇列:"; tmp=ready->next; while(tmp!=NULL){ cout<<" "<<tmp->name; tmp=tmp->next; } cout<<endl; cout<<"阻塞佇列:"; tmp=blocked->next; while(tmp!=NULL){ cout<<" "<<tmp->name; tmp=tmp->next; } cout<<endl; cout<<endl; } //選單 void menu() { cout<<"\t\t--------------------"<<endl; cout<<"\t\t1.創建行程"<<endl; cout<<"\t\t2.時間片到"<<endl; cout<<"\t\t3.阻塞行程"<<endl; cout<<"\t\t4.喚醒行程"<<endl;; cout<<"\t\t5.終止行程"<<endl; cout<<"\t\t6.退出程式"<<endl; cout<<"\t\t--------------------"<<endl; } main() { ready=(struct PCB*)malloc(sizeof(struct PCB)); ready->next=NULL; blocked=(struct PCB*)malloc(sizeof(struct PCB)); blocked->next=NULL; int c; while(1) { menu(); cout<<"輸入功能:"; cin>>c; switch(c) { case 1: creat(); break; case 2: timeout(); break; case 3: block(); break; case 4: wakeup(); break; case 5: stop(); break; case 6: exit(0); default: cout<<"沒有這個選項,請重新輸入"<<endl; } show(); } }
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/492104.html
標籤:C
