進程動態優先級調度

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

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 }

?

轉載于:https://www.cnblogs.com/A--Q/p/6104885.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/270431.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/270431.shtml
英文地址,請注明出處:http://en.pswp.cn/news/270431.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

電腦維修:如何給筆記本電腦升級內存條

??作者主頁&#xff1a;IT技術分享社區 ??作者簡介&#xff1a;大家好,我是IT技術分享社區的博主&#xff0c;從事C#、Java開發九年&#xff0c;對數據庫、C#、Java、前端、運維、電腦技巧等經驗豐富。 ??個人榮譽&#xff1a; 數據庫領域優質創作者&#x1f3c6;&#x…

php動態添加查詢,php動態添加url查詢參數的方法,php動態url參數_PHP教程

php動態添加url查詢參數的方法&#xff0c;php動態url參數本文實例講述了php動態添加url查詢參數的方法。分享給大家供大家參考。具體分析如下&#xff1a;這段代碼可以動態為url添加key-value查詢參數&#xff0c;如果參數已經存在則會用新的進行覆蓋function add_querystring…

Object o = new Object()在內存中占幾個字節

CAS&#xff1a; Compare and Swap&#xff0c;即比較再交換。 jdk5增加了并發包java.util.concurrent.*,其下面的類使用CAS算法實現了區別于synchronouse同步鎖的一種樂觀鎖。JDK 5之前Java語言是靠synchronized關鍵字保證同步的&#xff0c;這是一種獨占鎖&#xff0c;也是…

MYSQL筆記:刪除操作Delete、Truncate、Drop用法比較

今天小編給大家梳理一下MYSQL刪除操作Delete、Truncate、Drop用法有什么區別&#xff0c;到底該如何合理使用&#xff0c;希望對大家能有幫助&#xff01;1、執行速度比較Delete、Truncate、Drop關鍵字都可以刪除數據drop>truncate>delete2、原理方面2.1 deletedelete屬于…

php常用函數

//php curl get獲取head頭部跳轉參數function get_head($sUrl){$oCurl curl_init(); // 設置請求頭, 有時候需要,有時候不用,看請求網址是否有對應的要求$header[] "Content-type: application/x-www-form-urlencoded";$user_agent "Mozilla/5.0 (Windows NT…

partition oracle用法,Oracle partition by 使用說明

--用法詳解0、select * from wmg_test; ---測試數據1、select v1,v2,sum(v2) over(order by v2) as sum --按照 v2排序&#xff0c;累計nn-1....1from wmg_test;2、select v1,v2,sum(v2) over(partition by v1 order by v2) as sum --先分組&#xff0c;組內在進行…

SQLServer優化:SQLServer中NOLOCK關鍵字的用法介紹

目錄 1、為什么SQLServer有NOLOCK關鍵字&#xff1f; 2、SQLServer有NOLOCK有什么問題 3、NOLOCK使用場景 4、nolock和with(nolock)的區別 5、表解鎖腳本 1、為什么SQLServer有NOLOCK關鍵字&#xff1f; SQLServer沒創建一個查詢&#xff0c;都相當于創建一個查詢會話&#xff…

20144303 20145239 實驗三

20144303 20145239 實驗三 實驗內容 1、首先連接好實驗箱電源&#xff0c;用串口線、并口線、網線、連接實驗箱和主機 2、安裝ADS并破解 安裝文件在00-ads1.2目錄下&#xff0c;破解方法在00-ads1.2\Crack目錄下 3、安裝GIVEIO驅動(安裝文件在01-GIVEIO目錄下) 把整個GIVEIO目錄…

oracle無法創建監聽器,關于Oracle net Manager中點擊無法創建監聽程序的解決方案

首先查看你的環境變量中是否有如果沒有請添加該環境變量。變量名為&#xff1a;TNS_ADMIN 變量值為&#xff1a;E:\app\Administrator\product\11.2.0\dbhome_1\NETWORK\ADMIN;(如果你更改了默認目錄&#xff0c;請找到相應的目錄加進去)&#xff0c;添加完成之后&#xff0c;…

辦公技巧:分享5個非常好用的Excel插件

??作者主頁&#xff1a;IT技術分享社區 ??作者簡介&#xff1a;大家好,我是IT技術分享社區的博主&#xff0c;從事C#、Java開發九年&#xff0c;對數據庫、C#、Java、前端、運維、電腦技巧等經驗豐富。 ??個人榮譽&#xff1a; 數據庫領域優質創作者&#x1f3c6;&#x…

weblogic安全漫談

今天&#xff0c;我來與大家探討一下關于weblogic的話題 在進入內網后&#xff0c;如圖&#xff1a; 當我們看到7001時&#xff0c;我們就可以測試weblogic反序列化漏洞&#xff0c;如圖&#xff1a; 證明&#xff0c;漏洞存在&#xff0c;查看一下權限&#xff0c;如圖&#x…

linux使進程不依賴終端,Linux?nohup命令應用簡介--讓Linux的進程不受終端影響

nohup命令應用簡介--讓Linux的進程不受終端影響by:授客QQ&#xff1a;1033553122#開啟ping進程[rootlocalhost ~]# pinglocalhost &[2] 4169[1]Terminatednohup ping localhost[rootlocalhost ~]# PINGlocalhost (127.0.0.1) 56(84) bytes of data.64 bytes from localhost…

電腦技巧:Win10操作系統設置定時開機圖解教程

??作者主頁&#xff1a;IT技術分享社區 ??作者簡介&#xff1a;大家好,我是IT技術分享社區的博主&#xff0c;從事C#、Java開發九年&#xff0c;對數據庫、C#、Java、前端、運維、電腦技巧等經驗豐富。 ??個人榮譽&#xff1a; 數據庫領域優質創作者&#x1f3c6;&#x…

JavaScript對UNIX時間戳的轉換

<script type"text/javascript">   var timestamp 1479886513;   var d new Date(timestamp * 1000); //根據時間戳生成的時間對象   var date (d.getFullYear()) "-"     (d.getMonth() 1) "-"     (d.getDate())…

網絡技巧:想要WiFi信號滿格,路由器應該這樣放

現如今人手一部手機 不知不覺 WiFi也成了生活“必需品” 刷視頻正入迷視頻卻突然卡頓 換個房間就收不到WiFi信號 如此令人抓狂的事情 生活中你一定遇到過 其實 這與路由器的錯誤擺放有很大關系 家庭無線路由器 放置在哪里信號最好&#xff1f; WiFi信號差如何解決&#xff1f; …

linux系統export,Linux入門進階 - 如何在Linux中使用export命令

原標題&#xff1a;Linux入門進階 - 如何在Linux中使用export命令來自&#xff1a; Linux迷鏈接&#xff1a;https://www.linuxmi.com/linux-export.htmlLinux export命令會標記哪些值需要傳遞給一組子進程。這是bash shell提供的一個簡單但有用的特性。它允許管理員在不中斷當…

Duilib開發環境搭建

1.到github上下載最新版本&#xff0c;https://github.com/duilib/duilib&#xff0c;也沒有發現版本號&#xff0c;就如圖所示吧 2.我只安裝了VS2008&#xff0c;而github上的已經更新到VS2013了&#xff0c;所以要手動修改SIN工程文件 把sln文件打開&#xff0c;將最上面的2行…

手機技巧:手機丟了記住這四步操作,讓你的損失降到最低

隨著掃碼支付的普及、智慧生活的升級&#xff0c;沒有錢包能付賬&#xff0c;沒有公交卡能乘車&#xff0c;沒有銀行卡也能取款&#xff0c;只要你手機在手&#xff0c;手機手機錢包身份證銀行卡各種支付密碼。但你是否想過&#xff0c;如果某一天手機丟了&#xff0c;該怎么辦…