计算机操作系统实验之进程调度(一)轮转调度法(C语言)

进程调度有多种方法,前一周的实验只写了两个,打算每种方法都分开整理一下,就是不知道什么时候腾出时间写完了。今天就先说轮转调度法吧。

实验目的

1、理解进程调度的任务、机制和方式

2、了解轮转调度算法的基本原理

实验内容与基本要求

用C,C++等语言编写程序,模拟使用轮转调度算法实现进程调度

轮转调度法的基本原理

在轮转调度法中,系统根据FCFS(先来先服务)原则,把所有的就绪进程排成一个就绪队列,并可设置每隔一定时间间隔产生一次中断,当当前运行进程结束或者时间用完时,执行一次进程调度,将CPU分配给新的队首进程。这样可以保证所有进程在一个确定的时间段内,都可以获得一次CPU执行。

在这个算法中,隐含着一个基本假设:所有进程的紧迫性是一致的,这样才能按照其到达的先后顺序来执行。显然这在实际当中并不存在,因此才有了后面要说的优先级调度算法。
附:优先级调度法计算机操作系统实验之进程调度(二)优先级调度法(C语言)
轮转调度法中,需要考虑的核心问题是对时间片大小的确定。假如时间片选择过小,那么将会频繁地进行进程调度和切换,这样就增大了系统开销;而时间片选择过大,所有进程都能在一个时间片内完成,轮转法实际上就退化成了FCFS算法,无法满足短作业和交互式用户的需求。当然,我们实验中不考虑这个问题,只要设置好一个固定的时间片就行了。

实现思路及功能分析

要进行进程调度,依然要模拟出PCB的结构。在本次实验中,要求展示时间片、cpu时间等信息,因此设计PCB的属性包括:1.进程名字2.进程优先级3.进程的状态4.时间片5.总共需要的运行时间6.cpu时间(已运行时间)7.还需要运行的时间8.计数器9.下一个要执行的进程指针。

这样,我们使用带头结点的单链表来存储进程队列。按理来说,当进程运行结束后,应该将它移出队列,但是为了统一展示进程调度的过程、信息,已完成的进程不移出队列,而是沉到队列底部,只利用进程的状态属性来区分进程的完成情况。

实现轮转调度算法本质就是按插入进程队列的顺序依次运行,已完成的进程沉到队列最低端,直到所有进程都完成为止。因此进程队列逻辑上可以分成两个部分,前一部分是未完成的进程,后一部分是已完成的进程,当我们执行完一个进程,要将它调到队列尾部时,实际上调到的是未完成部分的尾部,已完成的部分不需要考虑。

因此执行完某个进程后,遍历链表寻找进程的插入位置时,停止遍历的条件有两个,第一个条件是结点的next值为空(此时该结点是最后一个结点,进程要插入的是链表最末尾),第二个条件是结点的next结点的状态为已完成(此时该结点往后均是已完成的结点,不需要考虑)

同时,因为原来的首元节点被调到了后方,它的下一个结点成为新的首元结点,我们遍历链表执行调度时只需要让指针保持指向首元结点即可。判断调度是否结束只需要判断首元结点的状态是否为已完成。若首元结点已完成,则说明它后面的结点也完成了。

对进程执行结束后的插入操作而言,并不关心进程是否已经完成,若它已经完成,则下次遍历到它前一个就会停止;没有完成,就会继续拿来执行。假设其他进程都完成后,还有一个进程需要运行多次,显然该进程开始所在的位置时首元结点,当运行完一个时间片后要为它寻找插入位置,由于首元结点往后的结点均为已完成,该结点被插入的为止仍是首元结点,然后被再次调出来执行,直到完成为止。

如图所示,当p1运行结束后,需要将p1移到队尾,首先让头指针指向p1的下一个结点,这样p1就脱离了整个链表,所以需要一个s指针记录它

img_1

遍历整个链表为p1寻找插入位置,在p指针指向的结点之后进行插入

img_2

要插入的位置有两种情况:第一个是队列的最末尾,这说明目前还没有已经完成的进程;第二个是队列中间,p结点之后都是已完成的进程。因为链表中在尾部插入和在两个结点之间插入涉及的指针操作有区别,所以要区分对待。

这样,p1就被移到了队列最尾部,在最后还需要将inedx指针指回首元结点,运行进程时,运行的始终是index指针指向的进程。

img_3

之所以说不需要考虑目前p1是否已经完成,是因为这样:当p2运行完后,用p指针遍历链表为p2寻找插入位置,假如p1没有完成,p指针仍会指到p1的位置,p2会插入到p1之后;假如p1已经完成,p指针只会指到p1的前一个结点,p2会插入到p1之前。以此类推,最先完成的进程会被沉到最底。

算法流程图

img_4

全部代码

工程图

img_5

ProcessScheduling.h
//
//  ProcessScheduling.h
//  ProcessSchedulingTest
//
//  Created by Apple on 2019/10/21.
//  Copyright © 2019 Yao YongXin. All rights reserved.
//

#ifndef ProcessScheduling_h
#define ProcessScheduling_h

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <time.h>

#define TIME_SLICE 2

//线程状态:就绪 等待 完成
enum process_type{
   
    process_type_waitting = 'W',
    process_type_ready = 'R',
    process_type_finish = 'F'
};

//进程控制块结构体
typedef struct PCB_Type{
   
    //进程的名字
    char *name;
    //进程的优先级
    int priority;
    //仍需运行时间
    int need_time;
    //进程的状态 就绪  等待
    char 
  • 19
    点赞
  • 141
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
操作系统进程调度计算机操作系统中的一个重要部分,它负责协调和管理系统中的各个进程,以实现资源的有效利用和任务的高效执行。在C语言中进行操作系统进程调度实验,可以通过模拟不同的调度来理解和掌握进程调度的原理和实现过程。 首先,可以使用C语言编写一个简单的程序,模拟进程的创建、就绪、运行和结束等状态。通过定义进程控制块(PCB)、进程队列等数据结构,以及编写相应的进程管理函数,来实现对进程的管理和调度。例如,可以编写函数来创建新进程、将进程加入就绪队列、根据调度选择下一个要执行的进程等。 其次,可以选择不同的调度实验,如先来先服务(FCFS)、最短作业优先(SJF)、时间片轮转(RR)等。针对不同的调度,通过C语言实现相应的调度函数,并在模拟程序中进行调用,观察不同算对进程执行顺序和响应时间的影响。 最后,可以通过对进程调度实验的结果进行分析和比较,来深入理解各种调度的优缺点,以及在不同场景下的适用性。同时,也可以通过进一步的实验和优化,来改进模拟程序,增加更多的实际场景和特性,以更好地理解和应用操作系统进程调度的相关知识。 通过C语言进行操作系统进程调度实验,可以帮助我们更深入地理解和掌握操作系统的核心概念和原理,为今后的系统设计和开发打下坚实的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值