操作系统课程:调度算法

多级反馈队列调度算法没有实现,其他均已实现,由于自己注释写的较少,所以不是很好的把代码表现出来!

下面附上实现的进程调度的代码:

  1 #include <stdio.h>

  2 #include <stdlib.h>

  3 #include <string.h>

  4 #include <time.h>

  5 

  6 #define maxnum 10

  7 #define getpch(type) (type* malloc(sizeof(type)))

  8 typedef struct pcb PCB;

  9 struct pcb{

 10     int id;

 11     char name[10];

 12     int time_start;//到达时间

 13     int time_need;// 服务时间

 14     int time_left;// 剩余运行时间

 15     int time_used;// 已经使用CPU时间

 16     char state;

 17 };

 18 

 19 void _sleep(int n){

 20     clock_t goal;

 21     goal = (clock_t)n * CLOCKS_PER_SEC + clock();

 22     while(goal > clock());

 23 }

 24 

 25 

 26 char _keygo(){

 27     char c;

 28     printf("....\n");

 29     c = getchar();

 30     return c;

 31 }

 32 

 33 int time_unit = 2;

 34 //const int maxnum = 10;

 35 int num = 5;

 36 PCB pcbdata[maxnum] = {

 37     {1000, "A", 0, 4, 4, 0, 'R'},

 38     {1001, "B", 1, 3, 3, 0, 'R'},

 39     {1002, "C", 2, 5, 5, 0, 'R'},

 40     {1003, "D", 3, 2, 2, 0, 'R'},

 41     {1004, "E", 4, 4, 4, 0, 'R'},

 42 };

 43 // PCB pcbdata[maxnum] = {

 44 //     {1000, "A", 1, 3, 3, 0, 'R'},

 45 //     {1001, "B", 1, 2, 2, 0, 'R'},

 46 //     {1002, "C", 5, 1, 1, 0, 'R'},

 47 //     {1003, "D", 6, 5, 5, 0, 'R'},

 48 //     {1004, "E", 6, 4, 4, 0, 'R'},

 49 // };

 50 // PCB pcbdata[maxnum] = {

 51 //     {1000, "A", 10, 8, 8, 0, 'R'},

 52 //     {1001, "B", 12, 14, 14, 0, 'R'},

 53 //     {1002, "C", 14, 4, 4, 0, 'R'},

 54 //     {1003, "D", 16, 6, 6, 0, 'R'},

 55 // };

 56 // PCB pcbdata[maxnum] = {

 57 //     {1000, "A", 8, 2, 4, 0, 'R'},

 58 //     {1001, "B", 8.5, 0.5, 3, 0, 'R'},

 59 //     {1002, "C", 9, 5, 0.1, 0, 'R'},

 60 //     {1003, "D", 9.5, 0.2, 2, 0, 'R'},

 61 // };

 62 int ready[maxnum];

 63 int order[maxnum];

 64 void input(){

 65     int i;

 66     printf("pid number is : ");

 67     scanf("%d", &num);

 68     for(i=0;i<num;++i){

 69         pcbdata[i].id = 1000+i;

 70         printf("input %d pid's name : ", i+1);

 71         scanf("%s", pcbdata[i].name);

 72         printf("input %d pid's start time: ", i+1); 

 73         scanf("%d", &pcbdata[i].time_start);

 74         printf("input %d pid's need time: ", i+1);

 75         scanf("%d", &pcbdata[i].time_need);

 76         pcbdata[i].time_left = pcbdata[i].time_need;

 77         printf("\n");

 78         pcbdata[i].time_used = 0;

 79         pcbdata[i].state = 'R';

 80     }

 81 }

 82 

 83 void _swap(int A[], int a, int b){

 84     int tmp;

 85     tmp = A[a];

 86     A[a] = A[b];

 87     A[b] = tmp;

 88 }

 89 

 90 void _swap1(PCB A[], int a, int b){

 91     PCB

 92      tmp;

 93     tmp = A[a];

 94     A[a] = A[b];

 95     A[b] = tmp;

 96 }

 97 

 98 int comp ( const void *a, const void *b )

 99 {

100     return (* ( PCB * ) a).time_start - (* ( PCB * ) b).time_start;

101 }

102 

103 int compID ( const void *a, const void *b )

104 {

105     return (* ( PCB * ) a).id - (* ( PCB * ) b).id;

106 }

107 

108 int compneed ( const void *a, const void *b )

109 {

110     return (* ( PCB * ) a).time_need - (* ( PCB * ) b).time_need;

111 }

112 

113 

114 //老师版本

115 void FCFS(){

116     int i, j, temp;

117     double k;

118     for(i=0;i<num;++i){

119         order[i] = pcbdata[i].time_start;

120         ready[i] = i;

121     }

122     for(i=0;i<num;++i)

123         for(j=i+1;j<num;++j){

124             if(order[i] > order[j]){

125                 _swap(order, i, j);

126                 _swap(ready, i, j);

127             }

128         }

129         printf("FCFS :\n");

130         temp = pcbdata[ready[0]].time_start;

131         for(i=0;i<num;++i){

132             printf("%d --> %s, ", i+1, pcbdata[ready[i]].name);

133             printf("start time -> %d, need time -> %d\n", pcbdata[ready[i]].time_start, pcbdata[ready[i]].time_need);

134             printf("The pid running ....\n");

135             _sleep(1);

136 

137             printf("Finish \n");

138             temp += pcbdata[ready[i]].time_need;

139             j = temp - pcbdata[ready[i]].time_start;

140             k = (float)j / pcbdata[ready[i]].time_need;

141             printf("The finish time ->%d, the zhouzhuan time ->%d, daiquan -> %.1f\n", temp, j, k);

142         }

143         printf("pid diaodu over!!\n");

144 }

145 

146 // 自己手写一个FCFS  快排版本!

147 void FCFS1(){

148     int i, j, temp=0;

149     double k;

150     qsort(pcbdata, num, sizeof(PCB), comp);//对进程进行的到达时间排序

151     printf("FCFS :\n");

152     temp = pcbdata[0].time_start;//此刻时间

153     for(i=0;i<num;++i){

154         printf("%d -> %s\n", i+1, pcbdata[i].name);//输出进程的名字

155         printf("start_time = %d, need time = %d\n", pcbdata[i].time_start, pcbdata[i].time_need);

156         //输出进程开始时间,服务时间

157         _sleep(1);

158         temp+=pcbdata[i].time_need;//结束时间

159         j = temp - pcbdata[i].time_start;//中转时间

160         k = (float)j / pcbdata[i].time_need;//带权中转时间

161         printf("The finist_time = %d, The zhongzhuan_time = %d, The daiquanzhongzhuan time = %g\n", temp, j, k);

162         //打印进程结束时间,中转时间,带权中转时间

163     }

164     printf("pid diaodu over !!\n");//调度结束

165 }

166 

167 

168 void SJF(){

169     int i, j, temp;

170     int mark = 0;

171     double k;

172     qsort(pcbdata, num, sizeof(PCB), comp);//对进程进行到达时间排序

173     printf("SJF : \n");

174     temp = pcbdata[0].time_start;//此刻时间

175     for(i=0;i<num;++i){

176         if(temp < pcbdata[num-1].time_start && !mark){//此刻时间小于最长到达时间的进程的到达时间

177             for(j=i+1;j<num;++j)

178                 if(temp<pcbdata[j].time_start){//如果此刻时间小于第j个进程的到达时间

179                     qsort(pcbdata+i, j-i, sizeof(PCB), compneed);//对第i+1到第j个进程进行到达服务时间排序

180                     break;

181                 }

182         }

183         else {

184             qsort(pcbdata+i, num-i, sizeof(PCB), compneed);//对第i+1进程到后面所有进程进行服务时间排序

185             mark = 1;//标记 代表所有进程已经全部到达

186         }

187         printf("%d -> %s\n", i+1, pcbdata[i].name);//输出进程名字

188         printf("start_time = %d, need time = %d\n", pcbdata[i].time_start, pcbdata[i].time_need);

189         //输出进程开始时间,服务时间

190         _sleep(1);

191         temp+=pcbdata[i].time_need;

192         j = temp - pcbdata[i].time_start;

193         k = (float)j / pcbdata[i].time_need;

194         printf("The finist_time = %d, The zhongzhuan_time = %d, The daiquanzhongzhuan time = %g\n", temp, j, k);

195     }

196     printf("pid diaodu over !!\n");

197 

198 }

199 

200 void HRF(){

201     int i, j, jj, temp, pos, mark;

202     double k;

203     mark = 0;

204     float w[10], max;

205     qsort(pcbdata, num, sizeof(PCB), comp);//对进程进行到达时间排序

206     printf("HRF: \n");

207     temp = pcbdata[0].time_start;//此刻时间

208     for(i=0;i<num;++i){    

209         if(i!=0 && i!=pos){

210             mark = 0;

211             _swap1(pcbdata, i, pos);//交换第i个进程和高响应比进程的位置

212             qsort(pcbdata+i, pos-i, sizeof(PCB), comp);//对除了选中的高响应比进程外其他进程进行到达时间排序

213         }

214         printf("%d -> %s\n", i+1, pcbdata[i].name);

215         printf("start_time = %d, need time = %d\n", pcbdata[i].time_start, pcbdata[i].time_need);

216         _sleep(1);

217         temp+=pcbdata[i].time_need;

218         jj = temp - pcbdata[i].time_start;

219         k = (float)jj / pcbdata[i].time_need;

220         max = 0;

221         for(j=i+1;j<num;++j){

222             if(temp > pcbdata[j].time_start){//如果现在时间大于到达时间

223                 w[j] = temp - pcbdata[j].time_start + pcbdata[j].time_need;//算出第j个进程的优先权

224                 w[j] /= pcbdata[j].time_need;//算优先权

225                 printf("w[%d] = %g ",j,  w[j]);//输出到达进程的所有进程的优先权值

226                 if(w[j] > max) {//计算最大优先权值的进程

227                     max = w[j];

228                     pos = j;//pos 为最大优先权值进程的数组标记

229                 }

230                 mark = 1;

231             }

232         }

233         printf("The finist_time = %d, The zhongzhuan_time = %d, The daiquanzhongzhuan time = %g, next weight = %g\n",temp, jj, k, max);

234         //输出进程结束时间,中转时间,带权中转时间,下一个优先权。

235     }

236 }

237 

238 //这是之前按照第一次老师讲解的方法所编写,由于第一次理论不是按进程执行后插到就绪队列末尾的方法,所以结果只是和老师之前有错的PPT 结果相同。

239 void _Timeslice(){

240     int i, j, temp, mark, gap, n, k;

241     float kk;

242     qsort(pcbdata, num, sizeof(PCB), comp);

243     mark = k = 0;

244     temp = pcbdata[0].time_start;

245     printf("Timeslice:\nThe gap is : ");

246     scanf("%d", &n);

247     int vis[maxnum];

248     memset(vis, 0, sizeof(vis));

249     while(1){

250         for(i=0;i<num;++i){

251             if(pcbdata[i].state == 'E') continue;

252             if(temp <= pcbdata[i].time_start && i!= 0 )  i = 0;

253             printf("temp : %d\n", temp);

254             ++k;

255             gap = n;

256             if(pcbdata[i].time_left >= gap)

257                 pcbdata[i].time_left -= gap;

258             else if(pcbdata[i].time_left > 0 && pcbdata[i].time_left < gap){

259                 gap = pcbdata[i].time_left;

260                 pcbdata[i].time_left = 0;

261             }

262             temp += gap;

263             pcbdata[i].time_used = pcbdata[i].time_need - pcbdata[i].time_left;

264             printf("%d -> %s, the gap : %d, the time_left: %d, the time_used : %d\n", k, pcbdata[i].name, gap, pcbdata[i].time_left, pcbdata[i].time_used);

265             if(pcbdata[i].time_left == 0){

266                 pcbdata[i].state = 'E';

267                 vis[i] = 1;

268                 j = temp - pcbdata[i].time_start;

269                 kk = (float)j / pcbdata[i].time_need;

270                 printf("The %s's state: %c ,The finist_time = %d, The zhongzhuan_time = %d, The daiquanzhongzhuan time = %g\n", pcbdata[i].name, pcbdata[i].state, temp, j, kk);

271             }

272             _sleep(1);

273         }

274         for(i=0;i<num;++i){

275             if(vis[i] == 1) mark = 1;

276             else{ mark = 0;break;}

277         }

278         if(mark == 1) break;

279     }

280 }

281 

282 //改进过的时间片轮转,按照第二次老师上课讲解的做法所编写,由于要维护动态就绪队列,所以用链表来模拟就绪队列。

283 typedef struct node *link;

284 typedef struct node {int data; link next;} Node;

285 //创建链表来模拟就绪队列

286 void insert(int data, link L){//尾插法插入元素

287     link y = malloc(sizeof(Node));

288     link p = L;

289     while(p->next) p = p->next;

290     y->data = data;

291     y->next = p->next;

292     p->next = y;

293 }

294 

295 void delete(link L){//从链表头部删除元素

296     L->next = L->next->next;

297 }

298 void Timeslice(){

299     int i, j, temp, mark, gap, n, k, pos;

300     float kk;

301     int vis[maxnum];

302     memset(vis, 0, sizeof(vis));

303     link L = malloc(sizeof *L);

304     L->next = 0;

305     k = 0;

306     qsort(pcbdata, num, sizeof(PCB), comp);//对进程进行到达时间排序

307     temp = pcbdata[0].time_start;

308     printf("Timeslice:\nThe gap is : ");

309     scanf("%d", &n);//输入时间片的长短

310     insert(0, L);

311     vis[0] = 1;

312     while(1){

313         ++k;

314         gap = n;

315         if(L->next){//如果链表有元素

316             pos = L->next->data;//pos 为链表的首元素

317             if(pcbdata[pos].time_left >= gap)//如果剩余时间大于时间片长度,就用剩余时间减去时间片长度

318                 pcbdata[pos].time_left -= gap;

319             else if(pcbdata[pos].time_left > 0 && pcbdata[pos].time_left < gap){

320             //如果剩余时间不大于时间片长度,则剩余时间为0,此刻的时间片长度等于剩余时间

321                 gap = pcbdata[pos].time_left;

322                 pcbdata[pos].time_left = 0;

323             }

324             temp += gap;

325             pcbdata[pos].time_used = pcbdata[pos].time_need - pcbdata[pos].time_left;//求CPU进程是用时间

326             printf("%d -> %s, the gap : %d, the time_left: %d, the time_used : %d\n", k, pcbdata[pos].name, gap, pcbdata[pos].time_left, pcbdata[pos].time_used);

327             //打印进程的剩余时间,使用时间

328             printf("The now time : %d\n", temp);

329             //打印此刻时间

330             if(pcbdata[pos].time_left == 0){//如果剩余时间为0,把进程状态从'R'改成‘E’

331                 pcbdata[pos].state = 'E';

332                 j = temp - pcbdata[pos].time_start;

333                 kk = (float)j / pcbdata[pos].time_need;

334                 printf("The %s's state: %c ,The finist_time = %d, The zhongzhuan_time = %d, The daiquanzhongzhuan time = %g\n", pcbdata[pos].name, pcbdata[pos].state, temp, j, kk);

335             }

336             _sleep(1);

337         }

338         else break;

339 

340         delete(L);//删除链表第一个元素,相当于维护就绪队列

341         for(i=0;i<num;++i){

342             if(vis[i]) continue;

343             if(!vis[i] && pcbdata[i].time_start<=temp){

344                 insert(i, L);

345                 vis[i] = 1;

346             }

347         }

348         if(pcbdata[pos].time_left > 0)//刚才执行过的进程插到就绪队列末尾

349             insert(pos, L);

350     }

351 }

352 

353 

354 

355 void MRLA(){}

356 

357 int main(int argc, char const *argv[])

358 {

359     int i = 0;

360     int sch = 99;

361     //input();

362     while(sch != 0){

363         qsort(pcbdata, num, sizeof(PCB), compID);//刚开始按进程ID顺序排序

364         printf("Please choose one diaodu : \n");

365         printf("1: FCFS\n");

366         printf("2: SJF\n");

367         printf("3: HRF\n");

368         printf("4: Timeslice\n");

369         printf("5: MRLA\n");

370         printf("0: exit\n");

371         printf("Please input a number :");

372         scanf("%d", &sch);

373         switch(sch){

374             case 1: FCFS();break;

375             case 2: SJF();    break;

376             case 3: HRF();    break;

377             case 4: Timeslice();break;

378             case 5:    MRLA();    break;

379             case 0: printf("exit the programe\n");break;

380         }

381     }

382     _keygo();

383     return 0;

384 }

 

 

 

 

你可能感兴趣的:(操作系统)