基于C++语言开发的Windows环境微型操作系统

Coquettish

发布日期: 2018-10-31 10:56:59 浏览量: 996
评分:
star star star star star star star star star star_border
*转载请注明来自write-bug.com

一 需求分析

用高级语言编写程序,模拟实现一个简单功能的操作系统。

  • 实现作业调度(先来先服务)、进程调度功能(时间片轮转)

  • 实现内存管理功能(连续分配)

  • 实现文件系统功能(选做内容)

  • 这些功能要有机地连接起来

二 程序设计

2.1 算法简介

先来先服务算法:

如果早就绪的进程排在就绪队列的前面,迟就绪的进程排在就绪队列的后面,那么先来先服务(FCFS: first come first service)总是把当前处于就绪队列之首的那个进程调度到运行状态。也就说,它只考虑进程进入就绪队列的先后,而不考虑它的下一个CPU周期的长短及其他因素。FCFS算法简单易行,但性能却不大好。

时间片轮转算法:

时间片轮转调度是一种最古老,最简单,最公平且使用最广的算法。每个进程被分配一个时间段,称作它的时间片,即该进程允许运行的时间。如果在时间片结束时进程还在运行,则CPU将被剥夺并分配给另一个进程。如果进程在时间片结束前阻塞或结束,则CPU当即进行切换。调度程序所要做的就是维护一张就绪进程列表,当进程用完它的时间片后,它被移到队列的末尾。

动态分配算法:

主要算法有首次适应算法、循环首次适应算法、最坏适应算法、最佳是适应算法等,是一种具有较高性能的内存分配算法。

三 程序实现

3.1 开发与运行环境

  • 运行系统:Windows 10

  • 编译工具:Dev C++

3.2 主要方法介绍

方法 功能
OS() 操作系统主界面
jobS() 作业调度算法(先来先服务)
courseS() 进程调度算法(时间片轮转)
memory() 内存管理算法

3.3 关键代码

作业调度

  1. /*
  2. 作业调度
  3. */
  4. typedef struct JCB { //定义进程控制块
  5. char num[2]; //作业号
  6. char name[10]; //作业名
  7. char state; //运行状态
  8. int tijiaotime; //提交作业时间
  9. int starttime; //作业开始时间
  10. int finishtime; //结束时间
  11. int needtime; //运行需要时间
  12. struct JCB *next; //指向下个作业
  13. }jcb;
  14. int time=10000,n; //计时器
  15. jcb *head=NULL,*p,*q;
  16. void run_fcfo(jcb *p1) {
  17. time = p1->tijiaotime > time? p1->tijiaotime:time;
  18. p1->starttime=time;
  19. printf("\n现在时间是%d,开始运行作业%s\n",time,p1->name);
  20. time+=p1->needtime;
  21. p1->state='F';
  22. p1->finishtime=time;
  23. printf("作业名 开始时间 所需时间 结束时间\n");
  24. printf("%s,%d,%d,%d",p1->name,p1->starttime,p1->needtime,p1->finishtime);
  25. }
  26. void fcfo() {
  27. int i,j,t;
  28. for(j=0;j<n;j++) {
  29. p=head;
  30. t=10000;
  31. for(i=0;i<n;i++) { //找到当前未完成的作业
  32. if(p->tijiaotime<t && p->state=='W') {
  33. t=p->tijiaotime;
  34. q=p; //标记当前未完成的作业
  35. }
  36. p=p->next;
  37. }
  38. run_fcfo(q);
  39. }
  40. }
  41. void getInfo() { //创建进程
  42. int num;
  43. printf("\n作业个数:");
  44. scanf("%d",&n);
  45. for(num=0;num<n;num++) {
  46. p=(jcb *)malloc(sizeof(jcb));
  47. if(head==NULL) {head=p;q=p;}
  48. printf("依次输入:\n作业号,作业名,提交时间,所需CPU时间\n");
  49. scanf("%s\t%s\t%d\t%d",&p->num,&p->name,&p->tijiaotime,&p->needtime);
  50. if(p->tijiaotime < time) time=p->tijiaotime;
  51. q->next=p;
  52. p->starttime=0;
  53. p->finishtime=0;
  54. p->next=NULL;
  55. p->state='W';
  56. q=p;
  57. }
  58. }
  59. void jobS() {
  60. printf("先来先服务算法模拟......");
  61. getInfo();
  62. fcfo();
  63. }

进程调度

  1. /*
  2. 进程调度
  3. */
  4. char pro[20] ; //进程
  5. int processNum; //进程数
  6. int timeSlice = 0; //时间片
  7. typedef char QlemTypeChar;
  8. typedef int QlemTypeInt;
  9. typedef int Status;
  10. typedef struct QNode {
  11. QlemTypeChar data;
  12. QlemTypeInt timeArrive = 0;
  13. QlemTypeInt timeService = 0;
  14. QlemTypeInt timeCount = 0;
  15. QlemTypeInt runCount = 0;
  16. QlemTypeInt timeFinal = 0; //完成时间
  17. QlemTypeInt timeRound = 0; //周转时间
  18. float timeRightRound = 0; //带权周转时间
  19. QlemTypeChar proState = 'W'; //进程的状态,W--就绪态,R--执行态,F--完成态
  20. struct QNode *next; //链表指针
  21. }QNode, *QueuePtr;
  22. typedef struct {
  23. QueuePtr front; //队头指针
  24. QueuePtr rear; //队尾指针
  25. }LinkQueue;
  26. Status InitQueue(LinkQueue &Q) {
  27. Q.front = Q.rear = (QueuePtr)malloc(sizeof(QNode));
  28. if(!Q.front) exit(OVERFLOW);
  29. Q.front->next = NULL;
  30. return OK;
  31. }
  32. Status EnQueue(LinkQueue &Q, QlemTypeChar e) {
  33. QueuePtr p;
  34. p = (QueuePtr)malloc(sizeof(QNode));
  35. if (!p) exit(OVERFLOW);
  36. p->data = e;
  37. p->next = NULL;
  38. Q.rear->next = p;
  39. Q.rear = p;
  40. return OK;
  41. }
  42. Status DeQueue(LinkQueue &Q, QlemTypeChar &e) {
  43. QueuePtr p;
  44. if (Q.front == Q.rear) return ERROR;
  45. p = Q.front->next;
  46. e = p->data;
  47. Q.front->next = p->next;
  48. if (Q.rear == p) Q.rear = Q.front;
  49. free(p);
  50. return OK;
  51. }
  52. LinkQueue QPro;
  53. QNode qq[10];
  54. void ProGetFirst() { //取出就绪队列队首进程
  55. InitQueue(QPro);
  56. printf("请输入要创建的进程名称:\n");
  57. for (int i = 0; i < processNum-1; i++) {
  58. fflush(stdin);
  59. scanf("%c", &pro[i]);
  60. }
  61. fflush(stdin);
  62. for (int i = 0; i<processNum-1; i++) {
  63. qq[i].data = pro[i];
  64. EnQueue(QPro, qq[i].data);
  65. }
  66. }
  67. void scanfData() {
  68. printf("请输入要创建的进程数目:");
  69. scanf("%d", &processNum);
  70. processNum++;
  71. fflush(stdin);
  72. printf("\n");
  73. ProGetFirst();
  74. printf("创建进程到达时间:\n");
  75. int time_Arr[10];
  76. for (int i = 0; i < processNum-1; i++) {
  77. scanf("%d", &time_Arr[i]);
  78. }
  79. for (int i =0; i<processNum-1; i++) {
  80. qq[i].timeArrive = time_Arr[i];
  81. EnQueue(QPro, qq[i].timeArrive);
  82. }
  83. printf("创建进程服务时间:\n");
  84. int time_Ser[10];
  85. for (int i = 0; i < processNum-1; i++) {
  86. scanf("%d", &time_Ser[i]);
  87. }
  88. for (int i = 0; i<processNum-1; i++) {
  89. qq[i].timeService = time_Ser[i];
  90. EnQueue(QPro, qq[i].timeService);
  91. }
  92. printf("请输入时间片大小::");
  93. scanf("%d", &timeSlice);
  94. printf("\n");
  95. }
  96. void ProOutPut1(){ //获取进程信息
  97. printf("进程名\t 到达时间\t 服务时间\t 进程状态\t 执行次数\n");
  98. for (int i = 0; i < processNum - 1; i++){
  99. printf("%c\t\t%d\t\t%d\t\t%c\t\t%d\n", qq[i].data, qq[i].timeArrive, qq[i].timeService, qq[i].proState, qq[i].runCount);
  100. }
  101. }
  102. void CalculatetimeFinal() { //计算完成时间
  103. int timecou=0;
  104. int countTemp = 0;
  105. QlemTypeChar ee;
  106. for (int i = 0; i < processNum - 1; i++) {
  107. countTemp += qq[i].timeService;
  108. }
  109. while (timecou < countTemp) {
  110. for (int i = 0; i < processNum - 1; i++) {
  111. if (qq[i].timeFinal == 0) {
  112. if (qq[i].timeService - qq[i].timeCount >= timeSlice) {
  113. timecou += timeSlice;
  114. }
  115. else {
  116. timecou += (qq[i].timeService - qq[i].timeCount);
  117. //DeQueue(QPro, ee);
  118. }
  119. if (timeSlice < qq[i].timeService) { //时间片大小< 服务时间
  120. int timetemp = timeSlice > qq[i].timeService ? qq[i].timeService : timeSlice;
  121. if ((qq[i].timeCount + timetemp) < qq[i].timeService) {
  122. if (qq[i].timeService - qq[i].timeCount >= timeSlice) {
  123. qq[i].timeCount += timeSlice;
  124. }
  125. else {
  126. qq[i].timeCount += (qq[i].timeService - qq[i].timeCount);
  127. }
  128. }
  129. else {
  130. if (qq[i].timeFinal == 0) {
  131. qq[i].timeFinal = timecou;
  132. }
  133. }
  134. }
  135. else { //时间片大小>= 服务时间
  136. qq[i].timeFinal = timecou; //该进程的完成时间=count
  137. }
  138. }
  139. }
  140. }
  141. for (int i = 0; i < processNum - 1; ++i) {
  142. qq[i].timeRound = qq[i].timeFinal - qq[i].timeArrive;
  143. qq[i].timeRightRound = (float)qq[i].timeRound / qq[i].timeService;
  144. }
  145. }
  146. void ProOutPut2() { //获取进程处理后的信息
  147. printf("进程名\t 到达时间 服务时间 完成时间 周转时间 带权周转\n");
  148. for (int i = 0; i < processNum - 1; i++) {
  149. printf("%c\t\t%d\t%d\t%d\t%d\t%.2f\n",
  150. qq[i].data, qq[i].timeArrive, qq[i].timeService, qq[i].timeFinal, qq[i].timeRound, qq[i].timeRightRound);
  151. }
  152. }
  153. int courseS() {
  154. scanfData();
  155. ProOutPut1();
  156. CalculatetimeFinal();
  157. printf("\n");
  158. printf("CPU处理中......\n");
  159. printf("完成时间:");
  160. for (int i = 0; i < processNum - 1; i++) {
  161. printf("%d,", qq[i].timeFinal);
  162. }
  163. printf("\n");
  164. printf("周转时间:");
  165. for (int i = 0; i < processNum - 1; i++) {
  166. printf("%d,",qq[i].timeRound);
  167. }
  168. printf("\n");
  169. printf("带权周转时间:");
  170. for (int i = 0; i < processNum - 1; i++) {
  171. printf("%.2f,", qq[i].timeRightRound);
  172. }
  173. printf("\n");
  174. ProOutPut2();
  175. return 0;
  176. }

内存管理

  1. /*
  2. 内存管理
  3. */
  4. typedef struct LNode {
  5. int startaddress;
  6. int size;
  7. int state;
  8. }LNode;
  9. LNode
  10. P[L]={{0,128,0},{200,256,0},{500,512,0},{1500,1600,0},{5000,150,0}};
  11. int N=5; int f=0;
  12. void print() {
  13. int i;
  14. printf("起始地址 分区 状态\n");
  15. for(i=0;i<N;i++)
  16. printf("%3d %8d %4d\n",P[i].startaddress,P[i].size,P[i].state);
  17. }
  18. void First() {
  19. int i,l=0,m;
  20. printf("\n输入请求分配分区的大小:");
  21. scanf("%d",&m);
  22. for(i=0;i<N;i++) {
  23. if(P[i].size<m)
  24. continue;
  25. else if(P[i].size==m) {
  26. P[i].state=1;
  27. l=1;
  28. break;
  29. }
  30. else {
  31. P[N].startaddress=P[i].startaddress+m;
  32. P[N].size=P[i].size-m;
  33. P[i].size=m;P[i].state=1;
  34. l=1;N++;
  35. break;
  36. }
  37. }
  38. if(l==1||i<N) {
  39. printf("地址成功分配\n\n");
  40. printf("地址分配成功后的状态:\n");
  41. print();
  42. }
  43. else
  44. printf("没有可以分配的地址空间\n");
  45. }
  46. void CirFirst() {
  47. int l=0,m,t=0;
  48. printf("\n输入请求分配分区的大小:");
  49. scanf("%d",&m);
  50. while(f<N) {
  51. if(P[f].size<m) {
  52. f=f+1;
  53. if(f%N==0) {
  54. f=0;t=1;
  55. }
  56. continue;
  57. }
  58. if(P[f].size==m && P[f].state!=1) {
  59. P[f].state=1;
  60. l=1;f++;
  61. break;
  62. }
  63. if(P[f].size>m && P[f].state!=1) {
  64. P[N].startaddress=P[f].startaddress+m;
  65. P[N].size=P[f].size-m;
  66. P[f].size=m;
  67. P[f].state=1;
  68. l=1;N++;f++;
  69. break;
  70. }
  71. }
  72. if(l==1) {
  73. printf("地址成功分配\n\n");
  74. printf("地址分配成功后的状态:\n");print();
  75. }
  76. else printf("没有可以分配的地址空间\n");
  77. }
  78. void Worst() {
  79. int i,t=0,l=0,m;
  80. int a[L];
  81. printf("\n输入请求分配分区的大小:");
  82. scanf("%d",&m);
  83. for(i=0;i<N;i++) {
  84. a[i]=0;
  85. if(P[i].size<m)
  86. continue;
  87. else if(P[i].size==m) {
  88. P[i].state=1;
  89. l=1;break;
  90. }
  91. else a[i]=P[i].size-m;
  92. }
  93. if(l==0) {
  94. for(i=0;i<N;i++) {
  95. if(a[i]!=0)
  96. t=i;
  97. }
  98. for(i=0;i<N;i++) {
  99. if(a[i]!=0 && a[i]>a[t])
  100. t=i;
  101. }
  102. P[N].startaddress=P[t].startaddress+m;
  103. P[N].size=P[t].size-m;
  104. P[t].size=m;P[t].state=1;
  105. l=1;N++;
  106. }
  107. if(l==1||i<N) {
  108. printf("地址成功分配\n\n");
  109. printf("地址分配成功后的状态:\n");
  110. print();
  111. }
  112. else printf("没有可以分配的地址空间\n");
  113. }
  114. void Best() {
  115. int i,t=0,l=0,m;
  116. int a[L];
  117. printf("\n输入请求分配分区的大小:");
  118. scanf("%d",&m);
  119. for(i=0;i<N;i++) {
  120. a[i]=0;
  121. if(P[i].size<m)
  122. continue;
  123. else if(P[i].size==m) {
  124. P[i].state=1;
  125. l=1;
  126. break;
  127. }
  128. else a[i]=P[i].size-m;
  129. }
  130. if(l==0) {
  131. for(i=0;i<N;i++) {
  132. if(a[i]!=0)
  133. t=i;
  134. }
  135. for(i=0;i<N;i++) {
  136. if(a[i]!=0 && a[i]<a[t])
  137. t=i;
  138. }
  139. P[N].startaddress=P[t].startaddress+m;
  140. P[N].size=P[t].size-m;
  141. P[t].size=m;P[t].state=1;
  142. l=1;N++;
  143. }
  144. if(l==1||i<N) {
  145. printf("地址成功分配\n\n");
  146. printf("地址分配成功后的状态:\n");
  147. print();
  148. }
  149. else printf("没有可以分配的地址空间\n");
  150. }
  151. void pr() {
  152. int k=0;
  153. printf("动态分区分配算法:");
  154. while(k!=5) {
  155. printf("\n~~~~~~~~主菜单~~~~~~~~~");
  156. printf("\n1、首次适应算法\n2、循环首次适应算法");
  157. printf("\n3、最坏适应算法\n4、最佳适应算法");
  158. printf("\n5、退出\n");
  159. printf("请选择算法:");
  160. scanf("%d",&k);
  161. switch(k) {
  162. case 1:
  163. printf("\n初始状态为:\n");
  164. print();
  165. First();
  166. continue;
  167. case 2:
  168. printf("\n初始状态为:\n");
  169. print();
  170. CirFirst();
  171. continue;
  172. case 3:
  173. printf("\n初始状态为:\n");
  174. print();
  175. Worst();
  176. continue;
  177. case 4:
  178. printf("\n初始状态为:\n");
  179. print();
  180. Best();
  181. continue;
  182. case 5:
  183. break;
  184. default:printf("选择错误,请重新选择。\n");
  185. }
  186. }
  187. }
  188. int memoryM() {
  189. pr();
  190. return 0;
  191. }

四 运行测试

运行界面如下:

上传的附件 cloud_download 基于C++语言开发的Windows环境微型操作系统.7z ( 159.06kb, 26次下载 )
error_outline 下载需要10点积分

keyboard_arrow_left上一篇 : 基于Android实现的页面置换模拟 基于VC++的MFC框架实现的飞机大战小游戏 : 下一篇keyboard_arrow_right



Coquettish
2018-10-31 10:58:34
作业调度功能、进程调度功能、内存管理功能、文件系统功能;操作系统;C++

发送私信

童心未泯,是一件值得骄傲的事情

29
文章数
19
评论数
最近文章
eject