操作系统,时间片轮转算法的C语言实现Round Robin

  1 #include "windows.h"
  2 #include <conio.h>
  3 #include <stdlib.h>
  4 #include <fstream.h>
  5 #include <io.h>
  6 #include <string.h>
  7 #include <stdio.h>
  8
  9 void Create_ProcInfo(); // 建立进程调度需要的数据
 10 void Display_ProcInfo();   // 显示当前系统全部进程的状态
 11 void Scheduler_FF();
 12 void Cpu_Sched();
 13 void IO_Sched();
 14 void NextRunProcess();
 15 void DisData();
 16 void DisResult();
 17
 18 int   RunPoint;   // 运行进程指针,-1时为没有运行进程
 19 int   WaitPoint;  // 阻塞队列指针,-1时为没有阻塞进程
 20 int   ReadyPoint; // 就绪队列指针,-1时为没有就绪进程
 21 long  ClockNumber;   // 系统时钟
 22 int   ProcNumber;    // 系统中模拟产生的进程总数
 23 int   FinishedProc;    // 系统中模拟产生的进程总数
 24 int q=9;//时间片
 25
 26
 27 //进程信息结构
 28 struct ProcStruct
 29 {
 30     int  p_pid;         // 进程的标识号
 31     char p_state;       // 进程的状态,C--运行  R--就绪  W--组塞  B--后备  F--完成
 32     int  p_rserial[16]; // 模拟的进程执行的CPU和I/O时间数据序列,间隔存储,0项存储有效项数
 33     int  p_pos;         // 当前进程运行到的序列位置
 34     int  p_starttime;   // 进程建立时间
 35     int  p_endtime;     // 进程运行结束时间
 36     int  p_cputime;     // 当前运行时间段进程剩余的需要运行时间
 37     int  p_iotime;      // 当前I/O时间段进程剩余的I/O时间
 38     int  p_next;        // 进程控制块的链接指针
 39     int  p_excutetime;  // 记录一次时间片内执行的时间
 40 } proc[10];
 41
 42 ////////////////////////////////////////////////////////////////////////////
 43 //
 44 //  随机生成进程数量和每个CPU--I/O时间数据序列,进程数量控制在5到10之间, //
 45 //  数据序列控制在6到12之间,CPU和I/O的时间数据值在5到15的范围           //
 46 //
 47 ////////////////////////////////////////////////////////////////////////////
 48
 49 void Create_ProcInfo(void )
 50 {
 51     int s,i,j;
 52
 53     srand(GetTickCount());                        // 初始化随机数队列的"种子"
 54     ProcNumber=((float) rand() / 32767) * 5 ;  // 随机产生进程数量5~10
 55
 56
 57     for(i=0;i<ProcNumber;i++)    // 生成进程的CPU--I/O时间数据序列
 58     {
 59         proc[i].p_pid=((float) rand() / 32767) * 1000;
 60         proc[i].p_state=‘B‘;   // 初始都为后备状态
 61
 62         s=((float) rand() / 32767) *6 + 2; // 产生的进程数据序列长度在6~12间
 63         proc[i].p_rserial[0]=s; // 第一项用于记录序列的长度
 64         for(j=1;j<=s;j++)  // 生成时间数据序列
 65             proc[i].p_rserial[j]=((float) rand() / 32767) *10 + 5;
 66         // 赋其他字段的值
 67         proc[i].p_pos=1;
 68         proc[i].p_starttime=((float) rand() / 32767) *49+1;   // 随机设定进程建立时间
 69         proc[i].p_endtime=0;
 70         proc[i].p_cputime=proc[i].p_rserial[1];
 71         proc[i].p_iotime=proc[i].p_rserial[2];
 72         proc[i].p_next=-1;
 73         proc[i].p_excutetime=0;
 74     }
 75     printf("\n---------------------------\n    建立了%2d 个进程数据序列\n\n", ProcNumber);
 76     DisData();
 77     printf("\nPress Any Key To Continue.......");
 78     _getch() ;
 79     return ;
 80 }
 81
 82 ////////////////////////////////////////////////////////////////////////
 83
 84 //                        显示系统当前状态
 85
 86 ////////////////////////////////////////////////////////////////////////
 87
 88 void Display_ProcInfo(void)
 89 {  int i,n;
 90
 91 system("cls") ;
 92 printf("时间片为%d",q);
 93 printf("\n        当前系统模拟%2d 个进程的运行    时钟:%ld\n\n", ProcNumber,ClockNumber);
 94
 95 printf("        就绪指针=%d, 运行指针=%d, 阻塞指针=%d\n\n",ReadyPoint,RunPoint,WaitPoint );
 96 if(RunPoint!= -1)
 97 {
 98        printf(" 当前运行的进程   No.%d ID:%d\n", RunPoint,proc[RunPoint].p_pid);
 99        printf("              %6d,%6d,%6d\n",proc[RunPoint].p_starttime,proc[RunPoint].p_rserial[proc[RunPoint].p_pos],proc[RunPoint].p_cputime);
100        printf("当前运行的进程执行的时间为%d",proc[RunPoint].p_excutetime);
101        printf("当前运行的进程执行的cpu时间为%d",proc[RunPoint].p_cputime);
102 }
103 else
104 printf(" 当前运行的进程ID:No Process Running !\n");
105
106 n=ReadyPoint;
107 printf("\n Ready Process ...... \n");
108 while(n!=-1) // 显示就绪进程信息
109 {
110        printf("     No.%d ID:%5d,%6d,%6d,%6d\n",n,proc[n].p_pid,proc[n].p_starttime,proc[n].p_rserial[proc[n].p_pos],proc[n].p_cputime );
111        n=proc[n].p_next;
112 }
113
114 n=WaitPoint;
115 printf("\n Waiting Process ...... \n");
116 while(n!=-1) // 显示阻塞进程信息
117 {
118        printf("     No.%d ID:%5d,%6d,%6d,%6d\n",n,proc[n].p_pid,proc[n].p_starttime,proc[n].p_rserial[proc[n].p_pos],proc[n].p_iotime);
119        n=proc[n].p_next;
120 }
121
122 printf("\n=================== 后备进程 ====================\n");
123 for(i=0; i<ProcNumber; i++)
124 if (proc[i].p_state==‘B‘)
125 printf("     No.%d ID:%5d,%6d\n",i,proc[i].p_pid,proc[i].p_starttime);
126
127 printf("\n================ 已经完成的进程 =================\n");
128 for(i=0; i<ProcNumber; i++)
129 if (proc[i].p_state==‘F‘)
130 printf("No.%d ID:%5d,%6d,%6d\n",i,proc[i].p_pid,proc[i].p_starttime,proc[i].p_endtime);
131
132 }
133
134 ////////////////////////////////////////////////////////////////////////
135
136 //              显示模拟执行的结果
137
138 ////////////////////////////////////////////////////////////////////////
139 void DisResult(void)
140 {  int i;
141 printf("\n---------------------------------\n");
142 for(i=0; i<ProcNumber; i++)
143 {
144     printf("ID=%4d> %2d ",proc[i].p_pid ,proc[i].p_rserial[0] );
145     printf("%4d,%4d",proc[i].p_starttime,proc[i].p_endtime);
146     printf("\n" );
147 }
148 }
149
150 ////////////////////////////////////////////////////////////////////////
151
152 //              显示进程数据序列
153
154 ////////////////////////////////////////////////////////////////////////
155 void DisData(void)
156 {  int i,j;
157
158 for(i=0; i<ProcNumber; i++)
159 {
160     printf("ID=%4d %2d > ",proc[i].p_pid ,proc[i].p_rserial[0] );
161     for(j=1; j<=proc[i].p_rserial[0];j++)
162         printf("%4d",proc[i].p_rserial[j]);
163     printf("\n" );
164 }
165 }
166 ////////////////////////////////////////////////////////////////////////
167
168 //              选择下一个可以运行的进程
169
170 ////////////////////////////////////////////////////////////////////////
171 void NextRunProcess(void)
172 {
173     if (ReadyPoint==-1) { RunPoint = -1; return;}  // 就绪队列也没有等待的进程
174
175        proc[ReadyPoint].p_state =‘C‘;     //ReadyPoint所指示的进程状态变为执行状态
176        RunPoint=ReadyPoint;
177        if( proc[ReadyPoint].p_excutetime==-1)//进程为执行成功,接着上次的cpu时间执行
178        {
179             proc[ReadyPoint].p_excutetime=0;
180        }
181        else
182        proc[ReadyPoint].p_cputime =proc[ReadyPoint].p_rserial[proc[ReadyPoint].p_pos] ;
183        ReadyPoint=proc[ReadyPoint].p_next;
184        proc[RunPoint].p_next = -1;
185
186 }
187 ////////////////////////////////////////////////////////////////////////
188
189 //              CPU调度
190
191 ////////////////////////////////////////////////////////////////////////
192
193 void Cpu_Sched(void)
194 {
195     int n;
196
197     if (RunPoint == -1)    // 没有进程在CPU上执行
198     {         NextRunProcess();    return;     }
199
200     proc[RunPoint].p_cputime--;      // 进程CPU执行时间减少1个时钟单位
201     proc[RunPoint].p_excutetime++;
202     if((proc[RunPoint].p_cputime == 0&&proc[RunPoint].p_excutetime<=q))//若时间片未完,但进程已经结束
203     {
204         //printf("若时间片未完,但进程已经结束\n");
205         proc[RunPoint].p_excutetime=0;//清空运行时间
206         // 进程完成本次CPU后的处理
207         if (proc[RunPoint].p_rserial[0]==proc[RunPoint].p_pos) //进程全部序列执行完成
208         {
209             FinishedProc++;
210             proc[RunPoint].p_state =‘F‘;
211             proc[RunPoint].p_endtime = ClockNumber;
212             RunPoint=-1;  //无进程执行
213             NextRunProcess();
214         }
215         else //进行IO操作,进入阻塞队列
216         {
217             proc[RunPoint].p_pos++;
218             proc[RunPoint].p_state =‘W‘;
219             proc[RunPoint].p_iotime =proc[RunPoint].p_rserial[proc[RunPoint].p_pos];
220             printf("进入阻塞队列\n");
221             n=WaitPoint;
222             if(n == -1) //是阻塞队列第一个I/O进程
223                 WaitPoint=RunPoint;
224             else
225             {    do //放入阻塞队列第尾
226             {
227                 if(proc[n].p_next == -1)
228                 { proc[n].p_next = RunPoint;
229                 break;
230                 }
231                 n=proc[n].p_next;
232             } while(n!=-1) ;
233             }
234             RunPoint=-1;
235             NextRunProcess();
236         }
237         return;
238     }
239     if(proc[RunPoint].p_cputime > 0&&proc[RunPoint].p_excutetime<q)//时间片未完 程序未执行结束 继续执行
240     {
241         //printf("时间片未完 程序未执行结束 继续执行\n");
242         return;
243     }
244     //{ printf("\n RunPoint=%d,ctime=%d",RunPoint,proc[RunPoint].p_cputime);getchar();return; }
245     if(proc[RunPoint].p_cputime > 0&&proc[RunPoint].p_excutetime==q)//时间片完,但是程序未执行完 放到就绪队列尾部
246     {
247         //printf("时间片完,但是程序未执行完 放到就绪队列尾部\n");
248         int n;
249         proc[RunPoint].p_state=‘R‘;     //    进程状态修改为就绪
250         proc[RunPoint].p_next=-1;
251         proc[RunPoint].p_excutetime=-1;//清空运行时间,-1代表程序未执行完成
252         if(ReadyPoint==-1) // 就绪队列无进程
253             ReadyPoint=RunPoint;
254         else      // 就绪队列有进程,放入队列尾
255         {
256             n=ReadyPoint;
257             while(proc[n].p_next!=-1) n=proc[n].p_next;
258             proc[n].p_next=RunPoint;
259         }
260         RunPoint=-1;
261         NextRunProcess(); //执行下一个进程
262     }
263
264 }
265
266
267
268 ////////////////////////////////////////////////////////////////////////
269
270 //              I/O调度
271
272 ////////////////////////////////////////////////////////////////////////
273
274 void IO_Sched(void)
275 {
276     int n,bk;
277
278     if (WaitPoint==-1) return;   // 没有等待I/O的进程,直接返回
279
280     proc[WaitPoint].p_iotime--;  // 进行1个时钟的I/O时间
281
282     if (proc[WaitPoint].p_iotime > 0) return; // 还没有完成本次I/O
283
284     // 进程的I/O完成处理
285     if (proc[WaitPoint].p_rserial[0]==proc[WaitPoint].p_pos) //进程全部任务执行完成
286     {
287         FinishedProc++;
288         proc[WaitPoint].p_endtime = ClockNumber;
289         proc[WaitPoint].p_state =‘F‘;
290
291         if(proc[WaitPoint].p_next==-1)
292         { WaitPoint=-1;return ;}
293         else //调度下一个进程进行I/O操作
294         {
295             n=proc[WaitPoint].p_next;
296             proc[WaitPoint].p_next=-1;
297             WaitPoint=n;
298             proc[WaitPoint].p_iotime =proc[WaitPoint].p_rserial[proc[WaitPoint].p_pos] ;
299             return ;
300         }
301     }
302     else //进行下次CPU操作,进就绪队列
303     {
304         bk=WaitPoint;
305         WaitPoint=proc[WaitPoint].p_next;
306
307         proc[bk].p_pos++;
308         proc[bk].p_state =‘R‘; //进程状态为就绪
309         proc[bk].p_cputime = proc[bk].p_rserial[proc[bk].p_pos];
310         proc[bk].p_next =-1;
311
312         n=ReadyPoint;
313         if(n == -1) //是就绪队列的第一个进程
314         {  ReadyPoint=bk;    return;    }
315         else
316         {  do
317         {
318             if(proc[n].p_next == -1) { proc[n].p_next = bk;  break ; }
319             n=proc[n].p_next;
320         }
321         while(n!=-1);
322         }
323     }
324     return ;
325 }
326
327
328
329
330
331 ////////////////////////////////////////////////////////////////////////
332
333 //              检查是否有新进程到达,有则放入就绪队列
334
335 ////////////////////////////////////////////////////////////////////////
336
337 void NewReadyProc(void)
338 {
339     int i,n;
340
341     for(i=0; i<ProcNumber; i++)
342     {
343         if (proc[i].p_starttime == ClockNumber) // 进程进入时间达到系统时间
344         {
345             proc[i].p_state=‘R‘;     //    进程状态修改为就绪
346             proc[i].p_next=-1;
347
348             if(ReadyPoint==-1) // 就绪队列无进程
349                 ReadyPoint=i;
350             else      // 就绪队列有进程,放入队列尾
351             {
352                 n=ReadyPoint;
353                 while(proc[n].p_next!=-1) n=proc[n].p_next;
354                 proc[n].p_next=i;
355             }
356         }
357     } // for
358     return;
359 }
360
361
362 ////////////////////////////////////////////////////////////////////////
363
364 //                         调度模拟算法
365
366 ////////////////////////////////////////////////////////////////////////
367
368 void Scheduler_FF(void)
369 {
370     FinishedProc=0;
371     if(ProcNumber==0)
372     { printf("    必须首先建立进程调度数据 !  \n");
373     system("cls");    return;
374     }
375
376     ClockNumber=0;// 时钟开始计时, 开始调度模拟
377     while(FinishedProc < ProcNumber) // 执行算法
378     {
379         ClockNumber++;  // 时钟前进1个单位
380         NewReadyProc(); // 判别新进程是否到达
381         Cpu_Sched();    // CPU调度
382         IO_Sched();     // IO调度
383         Display_ProcInfo(); //显示当前状态
384     }
385     DisResult();
386     getch();   return;
387 }
388
389 void Change_q(void)
390 {
391   scanf("%d",&q);
392 }
393
394 ///////////////////////////////////////////////////////////////////
395
396 //                          主函数
397
398 ///////////////////////////////////////////////////////////////////
399
400 int main(int argc, char* argv[])
401 {
402     char ch;
403
404     RunPoint=-1;   // 运行进程指针,-1时为没有运行进程
405     WaitPoint=-1;  // 阻塞队列指针,-1时为没有阻塞进程
406     ReadyPoint=-1; // 就绪队列指针,-1时为没有就绪进程
407     ClockNumber=0;   // 系统时钟
408     ProcNumber=0;    // 当前系统中的进程总数
409
410     system("cls") ;
411     while ( true )
412     {
413         printf("***********************************\n");
414         printf("     1: 建立进程调度数据序列 \n") ;
415         printf("     2: 执行调度算法\n") ;
416         printf("     3: 显示调度结果 \n") ;
417         printf("     4: 更改时间片 \n");
418         printf("     5: 退出\n") ;
419         printf("***********************************\n");
420         printf( "Enter your choice (1 ~ 5): ");
421
422         do{   //如果输入信息不正确,继续输入
423             ch = (char)_getch() ;
424         } while(ch != ‘1‘ && ch != ‘2‘&& ch != ‘3‘&& ch != ‘4‘&& ch != ‘5‘);
425
426         if(ch == ‘5‘) { printf( "\n");return 0; }   // 选择4,退出
427         if(ch == ‘3‘) DisResult();        // 选择3
428         if(ch == ‘2‘) Scheduler_FF();     // 选择2
429         if(ch == ‘1‘) Create_ProcInfo();  // 选择1
430         if(ch == ‘4‘) Change_q();
431         _getch() ;
432         system("cls") ;
433     }
434     //结束
435     printf("\nPress Any Key To Continue:");
436     _getch() ;
437     return 0;
438 }

原文地址:https://www.cnblogs.com/lancelee98/p/9991651.html

时间: 2024-10-10 03:19:14

操作系统,时间片轮转算法的C语言实现Round Robin的相关文章

时间片轮转算法和优先级调度算法模拟实现

实验三时间片轮转算法和优先级调度算法模拟实现 一.  实验任务 1. 设计进程控制块PCB的结构,通常应包括如下信息: 进程名.进程优先数(或轮转时间片数).进程已占用的CPU时间.进程到完成还需要的时间.进程的状态.当前队列指针等. 2.编写两种调度算法程序: 优先级调度算法 时间片轮转调度算法 3. 按要求输出结果. 二.实验目的 1. 加深理解有关进程控制块.进程队列等概念. 2. 体会和了解优先级调度算法和时间片轮转算法的具体实施办法. 三.实验环境 1. 一台运行Windows 7操作

无限大整数相加算法的C语言源代码

忙里偷闲,终于完成了无限大整数相加算法的C语言代码,无限大整数相加算法的算法分析在这里. 500位的加法运行1000次,不打印结果的情况下耗时0.036秒,打印结果的情况下耗时16.285秒. 下面是源码: #include <stdio.h> #include <stdlib.h> #include<string.h> #include <time.h> #define MAXNUM 1000000000000000000 /* 存储数据用的结构 long

排序算法总结(C语言版)

1.    插入排序 1.1     直接插入排序 1.2     Shell排序 2.    交换排序 2.1     冒泡排序 2.2     快速排序 3.    选择排序 3.1     直接选择排序 3.2     堆排序 4.    归并排序 4.1     二路归并排序 4.2     自然合并排序 5.    分布排序 5.1     基数排序 1.插入排序 1.1      直接插入排序 将已排好序的部分num[0]~num[i]后的一个元素num[i+1]插入到之前已排好序的

Bagging算法的R语言实现

bagging 是bootstrap aggregating的缩写,是第一批用于多分类集成算法. bagging算法如下: 循环K次,每次都从样本集D中有放回地抽取样本集Di,这样总共得到k个样本集,用这K个样本集进行决策树生成,获得K个决策树模型,再将要检测的数据用这K个决策树模型进行多数表决,获得票数多的结论. 这种思想跟现代民主投票制度如出一辙,一个人再厉害,判断力也是有限的,但是把一群人聚合在一起投票,那单个人所犯错误的概率就会被抵消,最后得出结论的正确性会明显优于单个人做出决策. 个人

深入排序算法的多语言实现

深入浅出排序算法的多语言实现 作者:白宁超 2015年10月8日20:08:11 摘要:十一假期于实验室无趣,逐研究起数据结构之排序.起初觉得就那么几种排序,两三天就搞定了,后来随着研究的深入,发觉里面有不少东西.本文介绍常用的排序算法,主要从以下几个方面:算法的介绍.算法思想.算法步骤.算法优缺点.算法实现.运行结果.算法优化等.最后对本文进行总结.本文为作者原创,程序经测试无误.部分资料引用论文和网络材料以及博客,后续参见参考文献.(本文原创,转载注明出处) 1 排序的基本概念 排序: 所谓

Kruskal算法的C语言实现(并查集版)

[问题] Kruskal算法求加权连通图的最小生成树的算法.kruskal算法总共选择n- 1条边,所使用的贪婪准则是:从剩下的边中选择一条不会产生环路的具有最小耗费的边加入已选择的边的集合中.注意到所选取的边若产生环路则不可能形成一棵生成树.kruskal算法分e 步,其中e 是网络中边的数目.按耗费递增的顺序来考虑这e 条边,每次考虑一条边.当考虑某条边时,若将其加入到已选边的集合中会出现环路,则将其抛弃,否则,将它选入. [代码] #include <stdio.h> #include

算法程序设计题语言类笔记

1. 求幂 #include<math.h> //头文件 pow(a,b); //a^b 2. bool #include<stdbool.h> //C中使用bool型需要加入头文件 3. 字符串操作相关 #include<string.h> //头文件 char a[20],b[20]; strcpy(a,b); //把字符串b拷贝到a中 length=strlen(); //求长度 strcmp(a,b); //字符串比较,将a和b中的字符逐个比较,相同继续比较下一

POS终端MAC算法-C语言实现

POS终端MAC算法-C语言实现

机器学习算法的R语言实现(二):决策树

1.介绍 ?决策树(decision tree)是一种有监督的机器学习算法,是一个分类算法.在给定训练集的条件下,生成一个自顶而下的决策树,树的根为起点,树的叶子为样本的分类,从根到叶子的路径就是一个样本进行分类的过程. ?下图为一个决策树的例子,见http://zh.wikipedia.org/wiki/%E5%86%B3%E7%AD%96%E6%A0%91 ? 可见,决策树上的判断节点是对某一个属性进行判断,生成的路径数量为该属性可能的取值,最终到叶子节点时,就完成一个分类(或预测).决策树