進程動態優先級調度


簡單的進程優先級動態調度

cup運行: 每執行一次,優先級減一,運行時間減一。

就緒隊列中的進程:每次按優先級降序排序(優先級越大越優先執行),若優先級相等再按時間升序排序(時間越小越優先執行)。

所用知識點:結構體數組、結構體排序。

  1 /*******************************************
  2 *
  3 *  File    : pro.c
  4 *  describe: 操作系統進程調度,動態優先級算法
  5 *  Author  : 阿Q
  6 *  Iime    : 2016.11.19
  7 *
  8 *******************************************/
  9 #include<stdio.h>
 10 #define P 5
 11 #define PrintF(proprety) printf("%s\t",proprety)
 12 struct pcb {         //定義進程結構
 13     int pid;             //進程Id
 14     struct pcb *next;  //指向下一個進程
 15     int time;    //進程所需執行的時間
 16     int priority;  //進程優先級
 17     int state;  //進程執行的狀態,只有0、1狀態.0未執行,1已執行
 18 };
 19 struct pcb pro[P]= {//初始化5個進程
 20     {0,1,6,3,0},
 21     {1,2,4,4,0},
 22     {2,3,4,3,0},
 23     {3,4,4,2,0},
 24     {4,0,1,0,0},
 25 };
 26 
 27 /*******************************************
 28 *
 29 *  Function : 顯示所有進程的狀態
 30 *
 31 *******************************************/
 32 void display() {
 33     int i=0,property=5;
 34     PrintF("\npid");
 35     for(i=0; i<P; i++) {
 36         printf("%d\t",pro[i].pid);
 37     }
 38     PrintF("\nnext");
 39     for(i=0; i<P; i++) {
 40         printf("%d\t",pro[i].next);
 41     }
 42     PrintF("\ntime");
 43     for(i=0; i<P; i++) {
 44         printf("%d\t",pro[i].time);
 45     }
 46     PrintF("\npri");
 47     for(i=0; i<P; i++) {
 48         printf("%d\t",pro[i].priority);
 49     }
 50     PrintF("\nstate");
 51     for(i=0; i<P; i++) {
 52         printf("%d\t",pro[i].state);
 53     }
 54     printf("\n");
 55 }
 56 
 57 /*******************************************
 58 *
 59 *  Function : 對結構體進行排序,按優先級降序*時間升序
 60 *
 61 *******************************************/
 62 int cmp(const void *a,const void *b) {
 63     struct pcb *aa=(struct pcb *)a;
 64     struct pcb *bb=(struct pcb *)b;
 65 
 66     //如果進程執行結束,則直接返回狀態
 67     if(aa->time==0||aa->state==1)return 1;
 68     else if(bb->time==0||bb->state==1)return -1;
 69 
 70     if(bb->priority!=aa->priority)
 71         return (bb->priority - aa->priority);
 72     else
 73         return (aa->time - bb->time);
 74 }
 75 
 76 /*******************************************
 77 *
 78 *  Function : 進程排序 需要子函數 cmp()
 79 *
 80 *******************************************/
 81 void reSort() {
 82     qsort(pro,P,sizeof(pro[0]),cmp);
 83 }
 84 
 85 /*******************************************
 86 *
 87 *  Function : 檢查是否存在未執行完的程序
 88 *
 89 *******************************************/
 90 int check() {
 91     int i=0;
 92     for(i=0; i<P; i++) {
 93         if(!pro[i].state)return 1;
 94     }
 95     return 0;
 96 }
 97 
 98 /*******************************************
 99 *
100 *  Function : 修改指針指向
101 *
102 *******************************************/
103 void rePoint() {
104     int i=0;
105     for(; i<P; i++) {
106         if(pro[i].state&&i>0) {
107             pro[i-1].next=0;
108         }
109         if(i<(P-1))
110             pro[i].next=pro[i+1].pid;
111     }
112 }
113 
114 int main() {
115     int f=0,i=1;
116     printf("初始狀態為:");
117     display();
118     while(check()) {//每執行完一次,測試是否還有進程未執行完
119         printf("第%d次運行后:",i++);
120         //pro[0]為第一個進程,這里當作是在CUP中執行的進程.每次執行執行時間減一,優先級減一。
121         pro[0].time-=1;//執行一次進程執行時間減一
122         pro[0].priority-=1;//動態優先級,每執行一次優先級減一
123 
124         if(pro[0].time==0)pro[0].state=1,pro[0].priority=-1,pro[0].next=0;//如果該進程執行完畢,及執行時間為0,則狀態該為1,同時調整優先級,指針調制為0
125         reSort();//重排進程
126         rePoint();//重排指針
127         display();//輸出
128     }
129     printf("進程以全部運行完畢\n");
130     return 0;
131 }

 

具有就緒隊列、阻塞隊列的動態優先級調度。

  1 /**********************************************************************************************************************
  2 *
  3 *  File      :  pro.cpp
  4 *  Time      :  2016.12.04
  5 *  Introduce :  CPU每執行一次,就緒隊列中進程優先級+1,CPU執行中的進程優先級-3,阻塞中的優先級不增加,增加阻塞時間。
  6 *  如果就緒隊列中進程的優先級比CPU中的進程優先級高,則CPU中的進程進入阻塞隊列,進程最長阻塞時間默認為3(每次+1,>=3,進入就緒隊列)。
  7 *
  8 **********************************************************************************************************************/
  9 #include<stdio.h>
 10 #include<stdlib.h>
 11 #define N 6
 12 
 13 // 待插入就緒隊列的進程數據
 14 int id[N]       = { 0,  1,  2,  3,  4,  5 };
 15 int priority[N] = { 14, 38, 27,  9,  7, 18 };
 16 int cpuTime[N]  = { 0,  0,  0,  0,  0,  0 };
 17 int allTime[N]  = { 5,  2,  3,  4,  2,  1 };
 18 
 19 
 20 /*********************************
 21 *
 22 *  模擬進程/PCB數據結構
 23 *
 24 *********************************/
 25 
 26 // 枚舉進程的狀態:就緒、執行、阻塞、完成
 27 enum STATE { Ready, Run, Block, Finish };
 28 
 29 
 30 // 建立PCB結構體
 31 struct PCB {
 32     int id;                     // 標志數
 33     int priority;               // 優先數
 34     int cpuTime;                // 已占CPU時間
 35     int allTime;                // 還需占CPU時間
 36     int blockTime;              // 已被阻塞的時間
 37     STATE state;                // 進程狀態
 38     PCB *pre;                   // PCB的前指針
 39     PCB *nxt;                   // PCB的后指針
 40 };
 41 
 42 
 43 /*********************************
 44 *
 45 *  模擬進程隊列
 46 *
 47 *********************************/
 48 
 49 // 進程入列
 50 void queQush(PCB *process, PCB *queHead) {
 51     process->pre = NULL;
 52     process->nxt = queHead->nxt;
 53     if(queHead->nxt != NULL) {
 54         // 非第一個入列
 55         queHead->nxt->pre = process;
 56     }
 57     queHead->nxt = process;
 58 }
 59 // 進程出列
 60 void quePop(PCB *process, PCB *queHead) {
 61     if(process->pre != NULL) {
 62         // 不是頭節點
 63         process->pre->nxt = process->nxt;
 64     } else {
 65         queHead->nxt = process->nxt;
 66     }
 67     if(process->nxt != NULL) {
 68         // 不是尾節點
 69         process->nxt->pre = process->pre;
 70     }
 71     // 清空進程指針
 72     process->pre = process->nxt = NULL;
 73 }
 74 // 查看隊列里進程的信息
 75 void queWalk(PCB *queHead) {
 76     PCB *pro = queHead->nxt;
 77     if(pro == NULL) {
 78         printf("(無進程)\n");
 79         return;
 80     }
 81     while(pro != NULL) {
 82         printf("id:%d,  pri:%d,  alltime:%d\n", pro->id,
 83                pro->priority, pro->allTime);
 84         pro = pro->nxt;
 85     }
 86 }
 87 
 88 /*********************************
 89 *
 90 *  模擬就緒隊列
 91 *
 92 **********************************/
 93 
 94 int readyQueNum;                // 就緒隊列的進程數量
 95 PCB readyQueHead;               // 就緒隊列的頭部
 96 PCB *readyMaxProcess;           // 就緒隊列中優先級最高的進程
 97 
 98 
 99 // 進程插入到就緒隊列
100 void readyQueQush(PCB *process) {
101     readyQueNum ++;
102     process->state = Ready;
103     queQush(process, &readyQueHead);
104 }
105 // 優先級最高的進程出列
106 PCB* readyQuePop() {
107     readyQueNum --;
108     quePop(readyMaxProcess, &readyQueHead);
109     return readyMaxProcess;
110 }
111 //更新就緒隊列
112 void readyQueUpdate() {
113     int maxPriority = -1;
114     PCB *pro = readyQueHead.nxt;
115     if(pro == NULL) {
116         // 就緒隊列沒有進程
117         readyMaxProcess = NULL;
118         return;
119     }
120     while(pro != NULL) {
121         pro->priority ++;
122         if(pro->priority > maxPriority) {
123             maxPriority = pro->priority;
124             readyMaxProcess = pro;
125         }
126         pro = pro->nxt;
127     }
128 }
129 // 返回就緒隊列最高優先級的值
130 int readyMaxPriority() {
131     return readyMaxProcess->priority;
132 }
133 // 查看就緒隊列里進程的信息
134 void readyQueWalk() {
135     printf("就緒隊列里的進程信息為:\n");
136     queWalk(&readyQueHead);
137 }
138 
139 
140 /*********************************
141 *
142 *  模擬阻塞隊列
143 *
144 *********************************/
145 
146 #define EndBlockTime 3          // 進程最長被阻塞時間
147 
148 
149 int blockQueNum;                // 阻塞隊列的進程數量
150 PCB blockQueHead;               // 阻塞隊列的頭部
151 PCB *blockMaxProcess;           // 阻塞隊列中優先級最高的進程
152 
153 
154 // 進程插入到阻塞隊列
155 void blockQueQush(PCB *process) {
156     blockQueNum ++;
157     process->blockTime = 0;
158     process->state = Block;
159     queQush(process, &blockQueHead);
160 }
161 // 優先級最高的進程出列
162 PCB* blockQuePop() {
163     blockQueNum --;
164     quePop(blockMaxProcess, &blockQueHead);
165     return blockMaxProcess;
166 }
167 // 每個時間片,更新阻塞隊列里進程的信息
168 void blockQueUpdate() {
169     int maxPriority = -1;
170     PCB *pro = blockQueHead.nxt;
171     while(pro != NULL) {
172         pro->blockTime ++;
173         if(pro->blockTime >= EndBlockTime) {
174             PCB *process = pro;
175             pro = pro->nxt;
176             // 阻塞時間到,調入就緒隊列
177             blockQueNum --;
178             quePop(process, &blockQueHead);
179             readyQueQush(process);
180         } else if(pro->priority > maxPriority) {
181             // 更新阻塞隊列里優先級最高的進程指針
182             maxPriority = pro->priority;
183             blockMaxProcess = pro;
184             pro = pro->nxt;
185         }
186     }
187 }
188 // 查看阻塞隊列里進程的信息
189 void blockQueWalk() {
190     printf("阻塞隊列里的進程信息為:\n");
191     queWalk(&blockQueHead);
192 }
193 
194 
195 /********************************
196 *
197 *  模擬動態優先權的進程調度
198 *
199 *********************************/
200 
201 // 初始化數據
202 void initData() {
203     // 初始化就緒隊列和阻塞隊列
204     readyQueNum = blockQueNum = 0;
205     readyMaxProcess = blockMaxProcess = NULL;
206     readyQueHead.pre = readyQueHead.nxt = NULL;
207     blockQueHead.pre = blockQueHead.nxt = NULL;
208     // 初始化進程進入就緒隊列
209     int i, maxPriority = -1;
210     for(i = 0; i < N; i ++) {
211         // 分配一個PCB的內存空間
212         PCB *pro = (PCB *)malloc(sizeof(PCB));
213         // 給當前的PCB賦值
214         pro->id        = id[i];
215         pro->priority  = priority[i];
216         pro->cpuTime   = cpuTime[i];
217         pro->allTime   = allTime[i];
218         pro->blockTime = 0;
219         if(pro->allTime > 0) {
220             // 插入到就緒隊列中
221             readyQueQush(pro);
222             // 更新就緒隊列優先級最高的進程指針
223             if(pro->priority > maxPriority) {
224                 maxPriority = pro->priority;
225                 readyMaxProcess = pro;
226             }
227         }
228     }
229 }
230 // 模擬cpu執行1個時間片的操作
231 void cpuWord(PCB *cpuProcess) {
232     cpuProcess->priority -= 3;//優先級-3
233     if(cpuProcess->priority < 0) {
234         cpuProcess->priority = 0;
235     }
236     cpuProcess->cpuTime ++;
237     cpuProcess->allTime --;
238     // 顯示正執行進程的信息:
239     printf("CPU正執行的進程信息為:\n");
240     printf("id:%d,  pri:%d,  alltime:%d\n", cpuProcess->id,
241            cpuProcess->priority, cpuProcess->allTime);
242 }
243 
244 
245 int main() {
246     int timeSlice   = 0;         // 模擬時間片
247     int cpuBusy     = 0;         // 模擬cpu狀態
248     PCB *cpuProcess = NULL;      // 當前在cpu執行的進程
249 
250     // 初始化數據
251     initData();
252     // 模擬進程調度
253     while(1) {
254         if(readyQueNum == 0 && blockQueNum == 0 && cpuBusy == 0) {
255             // 就緒隊列、阻塞隊列和cpu無進程,退出
256             break;
257         }
258         if(cpuBusy == 0) {
259             // cpu空閑,選擇一個進程進入cpu
260             if(readyQueNum > 0) {
261                 // 選擇緒隊列優先級最高的進程
262                 cpuProcess = readyQuePop();
263             } else {
264                 // 就緒隊列沒有進程,改為選擇阻塞隊列優先級最高的進程
265                 cpuProcess = blockQuePop();
266             }
267             cpuProcess->cpuTime = 0;
268             cpuProcess->state = Run;
269             cpuBusy = 1;
270         }
271         timeSlice ++;
272         printf("\n第%d個時間片后:\n", timeSlice);
273         // 模擬cpu執行1個時間片的操作
274         cpuWord(cpuProcess);
275         if(cpuProcess->allTime == 0) {
276             cpuProcess->state = Finish;
277             printf("\t--\t--\t--進程 %d 完成任務\n",cpuProcess->id);
278             // 釋放已完成進程的PCB
279             free(cpuProcess);
280             cpuBusy = 0;
281         }
282         // 更新就緒隊列和阻塞隊列里的進程信息
283         blockQueUpdate();
284         readyQueUpdate();
285         // 查看就緒隊列和阻塞隊列的進程信息
286         readyQueWalk();
287         blockQueWalk();
288         if(cpuBusy == 1 && readyQueNum >0 &&
289                 cpuProcess->priority < readyMaxPriority()) {
290             // 需搶占cpu,當前執行的進程調入阻塞隊列
291             blockQueQush(cpuProcess);
292             cpuProcess = readyQuePop();
293         }
294     }
295     printf("\n模擬進程調度算法結束\n");
296     return 0;
297 }

 


免責聲明!

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



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