fork(1) download
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. #define MAX_PROCESS 10 // 最大进程数
  6.  
  7. // 进程控制块 PCB
  8. typedef struct PCB {
  9. char name[20]; // 进程名
  10. int priority; // 优先数(数值越大优先级越高)
  11. int need_time; // 需要运行时间
  12. int run_time; // 已运行时间
  13. char state; // 进程状态:'R'就绪, 'r'运行, 'F'完成
  14. struct PCB *next; // 指向下一个进程的指针
  15. } PCB;
  16.  
  17. PCB *ready = NULL; // 就绪队列头指针
  18. PCB *running = NULL; // 当前运行进程
  19.  
  20. // 函数声明
  21. void init_process(); // 初始化进程
  22. void insert_ready(PCB *p); // 按优先级插入就绪队列
  23. PCB *get_highest_priority(); // 获取优先级最高的进程
  24. void print_queue(); // 打印就绪队列
  25. void schedule(); // 调度函数
  26. void run_process(); // 运行进程
  27. void destroy_process(PCB *p); // 撤销进程
  28.  
  29. // 初始化进程信息(可手动输入或预置)
  30. void init_process() {
  31. int n, i;
  32. PCB *p;
  33. printf("===== 进程调度模拟程序(最高优先数优先)=====\n\n");
  34. printf("请输入进程数量(最多%d个): ", MAX_PROCESS);
  35. scanf("%d", &n);
  36.  
  37. if (n <= 0 || n > MAX_PROCESS) {
  38. printf("进程数量不合法!\n");
  39. return;
  40. }
  41.  
  42. for (i = 0; i < n; i++) {
  43. p = (PCB *)malloc(sizeof(PCB));
  44. if (p == NULL) {
  45. printf("内存分配失败!\n");
  46. return;
  47. }
  48.  
  49. printf("\n--- 输入第%d个进程信息 ---\n", i + 1);
  50. printf("进程名: ");
  51. scanf("%s", p->name);
  52. printf("优先数(数值越大优先级越高): ");
  53. scanf("%d", &p->priority);
  54. printf("需要运行时间: ");
  55. scanf("%d", &p->need_time);
  56.  
  57. p->run_time = 0;
  58. p->state = 'R'; // 初始状态为就绪
  59. p->next = NULL;
  60.  
  61. insert_ready(p); // 插入就绪队列
  62. }
  63. }
  64.  
  65. // 按优先级从高到低插入就绪队列(优先级相同则按先来先服务)
  66. void insert_ready(PCB *p) {
  67. PCB *curr, *prev;
  68.  
  69. if (ready == NULL) {
  70. // 队列为空
  71. ready = p;
  72. p->next = NULL;
  73. return;
  74. }
  75.  
  76. // 找到插入位置(优先级降序)
  77. prev = NULL;
  78. curr = ready;
  79. while (curr != NULL && curr->priority >= p->priority) {
  80. prev = curr;
  81. curr = curr->next;
  82. }
  83.  
  84. if (prev == NULL) {
  85. // 插入队首
  86. p->next = ready;
  87. ready = p;
  88. } else {
  89. // 插入中间或队尾
  90. p->next = curr;
  91. prev->next = p;
  92. }
  93. }
  94.  
  95. // 取出就绪队列中优先级最高的进程
  96. PCB *get_highest_priority() {
  97. PCB *p;
  98. if (ready == NULL) return NULL;
  99.  
  100. p = ready;
  101. ready = ready->next;
  102. p->next = NULL;
  103. return p;
  104. }
  105.  
  106. // 打印当前就绪队列状态
  107. void print_queue() {
  108. PCB *p = ready;
  109. printf("\n【当前就绪队列状态】\n");
  110. if (p == NULL) {
  111. printf(" 就绪队列为空\n");
  112. return;
  113. }
  114.  
  115. printf(" 队首 -> ");
  116. while (p != NULL) {
  117. printf("[%s|优先数:%d|需时:%d|已运行:%d|状态:%c] -> ",
  118. p->name, p->priority, p->need_time, p->run_time, p->state);
  119. p = p->next;
  120. }
  121. printf("队尾\n");
  122. }
  123.  
  124. // 打印当前运行进程
  125. void print_running() {
  126. if (running != NULL) {
  127. printf("\n【当前运行进程】\n");
  128. printf(" [%s|优先数:%d|需时:%d|已运行:%d|状态:%c]\n",
  129. running->name, running->priority, running->need_time, running->run_time, running->state);
  130. }
  131. }
  132.  
  133. // 调度函数:选择优先级最高的进程投入运行
  134. void schedule() {
  135. if (running != NULL) return; // 已有运行进程
  136.  
  137. running = get_highest_priority();
  138. if (running != NULL) {
  139. running->state = 'r'; // 置为运行态
  140. }
  141. }
  142.  
  143. // 运行当前进程一个时间片
  144. void run_process() {
  145. if (running == NULL) {
  146. printf("当前没有运行进程!\n");
  147. return;
  148. }
  149.  
  150. printf("\n========================================\n");
  151. printf(">>> 正在运行进程: %s\n", running->name);
  152. printf(">>> 运行前: 优先数=%d, 已运行=%d, 需运行=%d\n",
  153. running->priority, running->run_time, running->need_time);
  154.  
  155. running->run_time++; // 已运行时间加1
  156. running->priority--; // 动态优先数:运行一次后优先级降低1
  157.  
  158. printf(">>> 运行后: 优先数=%d, 已运行=%d\n", running->priority, running->run_time);
  159.  
  160. // 检查进程是否完成
  161. if (running->run_time >= running->need_time) {
  162. running->state = 'F'; // 置为完成态
  163. printf(">>> 进程 %s 运行完毕!\n", running->name);
  164. destroy_process(running);
  165. running = NULL;
  166. } else {
  167. // 未完成,重新放回就绪队列
  168. running->state = 'R';
  169. printf(">>> 进程 %s 时间片用完,重新进入就绪队列\n", running->name);
  170. insert_ready(running);
  171. running = NULL;
  172. }
  173. }
  174.  
  175. // 撤销进程(释放内存)
  176. void destroy_process(PCB *p) {
  177. if (p != NULL) {
  178. printf(">>> 撤销进程 %s,释放资源\n", p->name);
  179. free(p);
  180. }
  181. }
  182.  
  183. // 主函数
  184. int main() {
  185. int choice;
  186. int step = 1;
  187.  
  188. init_process(); // 初始化进程
  189.  
  190. if (ready == NULL) {
  191. printf("没有创建任何进程,程序退出。\n");
  192. return 0;
  193. }
  194.  
  195. printf("\n========================================");
  196. printf("\n进程初始化完成,开始调度...\n");
  197. print_queue();
  198.  
  199. // 调度循环
  200. while (ready != NULL || running != NULL) {
  201. printf("\n========================================");
  202. printf("\n【第 %d 轮调度】\n", step++);
  203.  
  204. schedule(); // 调度
  205. print_running(); // 显示运行进程
  206. run_process(); // 运行进程
  207. print_queue(); // 显示就绪队列
  208.  
  209. printf("\n按回车键继续下一轮调度(输入0退出)...");
  210. choice = getchar();
  211. if (choice == '0') {
  212. printf("用户选择退出调度。\n");
  213. break;
  214. }
  215. // 清除缓冲区
  216. while (getchar() != '\n');
  217. }
  218.  
  219. printf("\n========================================\n");
  220. printf("所有进程调度完成!\n");
  221.  
  222. return 0;
  223. }
Success #stdin #stdout 0s 5316KB
stdin
Standard input is empty
stdout
===== 进程调度模拟程序(最高优先数优先)=====

请输入进程数量(最多10个): 进程数量不合法!
没有创建任何进程,程序退出。