1.打开终端,gedit scheduler.c,输入以下内容,保存

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 定义进程控制块
typedef struct pcb {
char name[10]; // 进程名
char state; // 进程状态:'W'表示就绪,'R'表示运行,'F'表示完成
int nice; // 进程优先数
int ntime; // 需要运行的时间
int rtime; // 已经运行的时间
struct pcb* link; // 指向下一个进程控制块的指针
} PCB;

// 全局变量,指向就绪队列的头
PCB *ready = NULL, *p;

// 进程优先数排序函数,优先数大者优先,并生成就绪队列
void sort() {
PCB *first, *second;
int insert = 0;
if ((ready == NULL) || (p->nice > ready->nice)) {
// 优先数最大者插入队首
p->link = ready;
ready = p;
} else {
// 对进程比较优先数,并调整它们的位置
first = ready;
second = first->link;
while (second != NULL) {
if (p->nice > second->nice) { // 若插入的进程比当前进程的优先数大
p->link = second;
first->link = p; // 插到当前进程的前面
second = NULL;
insert = 1;
} else {
first = first->link;
second = second->link;
}
}
// 若插入的进程优先数最小,则插到队尾
if (insert == 0) first->link = p;
}
}

// 输入各个进程参数,建立进程控制块并排序生成就绪队列
void input() {
int i, num;
printf("\n请输入被调度的进程数目:");
scanf("%d", &num);
for (i = 0; i < num; i++) {
printf("\n进程号No.%d:", i);
p = (PCB*) malloc(sizeof(PCB));
printf("\n输入进程名:");
scanf("%s", p->name);
printf("输入进程优先数:");
scanf("%d", &p->nice);
printf("输入进程运行时间:");
scanf("%d", &p->ntime);
printf("\n");
p->rtime = 0;
p->state = 'W';
p->link = NULL;
sort(); // 调用sort()函数
}
}

// 链表中节点个数的统计函数
int space() {
int len = 0;
PCB* pr = ready;
while (pr != NULL) {
pr = pr->link;
len++;
}
return len;
}

// 进程显示函数,用于显示当前进程
void disp(PCB *pr) {
printf("\n name \t state \t nice \t ntime \t rtime \n");
printf("%s\t", pr->name);
printf("%c\t", pr->state);
printf("%d\t", pr->nice);
printf("%d\t", pr->ntime);
printf("%d\t", pr->rtime);
printf("\n");
}

// 进程查看函数
void check() {
PCB* pr;
printf("\n**** 当前正在运行的进程是:%s", p->name);
disp(p);
pr = ready;
if (pr != NULL)
printf("\n**** 当前就绪队列状态为:");
else
printf("\n**** 当前就绪队列状态为:空\n");
while (pr != NULL) {
disp(pr);
pr = pr->link;
}
}

// 建立进程撤销函数(进程运行结束,撤销进程)
void destroy() {
printf("进程 [%s] 已完成.\n", p->name);
free(p);
}

// 建立进程就绪函数(进程运行时间到,设置进程处于就绪状态)
void running() {
p->rtime++;
if (p->rtime == p->ntime) {
p->state = 'F'; // 运行结束
destroy(); // 调用destroy()函数
} else {
p->nice--; // 优先数降低一级
p->state = 'W'; // 重新进入就绪队列
sort(); // 调用sort()函数
}
}

// 主函数
int main() {
int len, h = 0;
char ch;
input(); // 输入进程信息
len = space(); // 获取就绪队列长度
while ((len != 0) && (ready != NULL)) {
ch = getchar();
h++;
printf("\n The execute number: %d", h);
p = ready;
ready = p->link;
p->link = NULL;
p->state = 'R';
check();
running();
printf("\n按任意键继续......");
ch = getchar();
len = space(); // 更新就绪队列长度
}
printf("\n\n所有进程已经运行完成!\n");
ch = getchar();
return 0;
}

2.在命令行中编译代码:

1
gcc -o scheduler scheduler.c

3.运行程序:

1
./scheduler

根据提示输入进程数目、进程名、优先数和运行时间,程序将模拟进程调度并输出每次调度的结果,直到所有进程完成。

照书抄的内容,可参考:
image-20240928090657134