【操作系统】实验四 进程调度

news2024/12/24 8:28:00

实验名称: 实验四 进程调度

实验目的:  

1. 加深理解有关进程控制块、进程队列的概念

2. 体会和了解优先级和时间片轮转调度算法的具体实施办法

实验内容:

1. 设计进程控制块 PCB 表结构(与实验一的结构相同),分别适用于优先级调度算法和循环轮转调度算法,建立进程就绪队列。实现优先数调度循环轮转调度两种调度算法

#include <stdio.h>

#include <stdlib.h>

#include <string.h>



typedef struct node

{

    char name[20];

    int prio;

    int round;

    int cputime;

    int needtime;

    char state;

    int count;

    struct node *next;

} PCB;



PCB *ready = NULL, *run = NULL, *finish = NULL;

int num;



void GetFirst();

void Output(char algorithm_type, int current_time);

void InsertPrio(PCB *in);

void InsertTime(PCB *in);

void InsertFinish(PCB *in);

void PrioCreate();

void TimeCreate();

void Priority();

void RoundRun();

int main(void)

{

    char chose;

    printf("请输入要创建的进程数目:\n");

    scanf("%d", &num);

    getchar();

    printf("输入进程的调度方法:(P/R)\n");

    scanf("%c", &chose);

    switch (chose)

    {

    case 'P':

    case 'p':

        PrioCreate();

        Priority();

        break;

    case 'R':

    case 'r':

        TimeCreate();

        RoundRun();

        break;

    default:

        break;

    }

    Output(chose, -1);

    return 0;

}



void GetFirst()

{

    run = ready;



    if (ready != NULL)

    {

        run->state = 'R';

        ready = ready->next;

        run->next = NULL;

    }

}



void Output(char algorithm_type, int current_time)

{

    PCB *p;

    printf("CPUTIME:%d\n", current_time); // 修改这里,加上 + 1

    if (algorithm_type == 'P' || algorithm_type == 'p')

    {

        printf("NAME\tCPUTIME\tNEEDTIME\tPRIORITY\tSTATE\tCOUNT\n");

        p = ready;

        while (p != NULL)

        {

            printf("%s\t%d\t%d\t%d\t\t%c\t\t%d\n", p->name, p->cputime, p->needtime, p->prio, p->state, p->count);

            p = p->next;

        }

    }

    else if (algorithm_type == 'R' || algorithm_type == 'r')

    {

        printf("NAME\tCPUTIME\tNEEDTIME\tCOUNT\tSTATE\n");

        p = run;

        while (p != NULL)

        {

            printf("%s\t%d\t%d\t%d\t\t%c\t\t%d\n", p->name, p->cputime, p->needtime, p->count, p->state, p->count);

            p = p->next;

        }

    }

    p = finish;

    while (p != NULL)

    {

        printf("%s\t%d\t%d\t%d\t\t%c\t\t%d\n", p->name, p->cputime, p->needtime, p->prio, p->state, p->count);

        p = p->next;

    }

}



void InsertPrio(PCB *in)

{

    PCB *fst, *nxt;

    fst = nxt = ready;



    if (ready == NULL)

    {

        in->next = ready;

        ready = in;

    }

    else

    {

        if (in->prio > fst->prio)

        {

            in->next = ready;

            ready = in;

        }

        else

        {

            while (fst->next != NULL)

            {

                nxt = fst;

                fst = fst->next;

            }



            if (fst->next == NULL)

            {

                in->next = fst->next;

                fst->next = in;

            }

            else

            {

                nxt = in;

                in->next = fst;

            }

        }

    }

}



void InsertTime(PCB *in)

{

    PCB *fst;

    fst = ready;



    if (ready == NULL)

    {

        in->next = ready;

        ready = in;

    }

    else

    {

        while (fst->next != NULL)

        {

            fst = fst->next;

        }

        in->next = fst->next;

        fst->next = in;

    }

}



void InsertFinish(PCB *in)

{

    PCB *fst;

    fst = finish;



    if (finish == NULL)

    {

        in->next = finish;

        finish = in;

    }

    else

    {

        while (fst->next != NULL)

        {

            fst = fst->next;

        }

        in->next = fst->next;

        fst->next = in;

    }

}



void PrioCreate()

{

    PCB *tmp;

    int i;



    printf("输入进程名字和进程所需时间:\n");

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

    {

        if ((tmp = (PCB *)malloc(sizeof(PCB))) == NULL)

        {

            perror("malloc");

            exit(1);

        }

        scanf("%s", tmp->name);

        getchar();

        scanf("%d", &(tmp->needtime));

        tmp->cputime = 0;

        tmp->state = 'W';

        tmp->prio = 50 - tmp->needtime;

        tmp->round = 0;

        tmp->count = 0;

        InsertPrio(tmp);

    }

}



void TimeCreate()

{

    PCB *tmp;

    int i;



    printf("输入进程名字和进程时间片所需时间:\n");

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

    {

        if ((tmp = (PCB *)malloc(sizeof(PCB))) == NULL)

        {

            perror("malloc");

            exit(1);

        }

        scanf("%s", tmp->name);

        getchar();

        scanf("%d", &(tmp->needtime));

        tmp->cputime = 0;

        tmp->state = 'W';

        tmp->prio = 0;

        tmp->round = 2;

        tmp->count = 0;

        InsertTime(tmp);

    }

}



void Priority()

{

    int flag = 1;

    int current_time = 0;



    GetFirst();

    while (run != NULL)

    {

        current_time++;

        Output('P', current_time);

        while (flag)

        {

            run->prio -= 3;

            run->cputime++;

            run->needtime--;

            if (run->needtime == 0)

            {

                run->state = 'F';

                run->count++;

                InsertFinish(run);

                flag = 0;

            }

            else

            {

                run->state = 'W';

                run->count++;

                InsertTime(run);

                flag = 0;

            }

        }

        flag = 1;

        GetFirst();

    }

}



void RoundRun()

{

    int flag = 1;

    int current_time = 0;



    GetFirst();

    while (run != NULL)

    {

        current_time++;

        Output('R', current_time);

        flag = 1;

        while (flag)

        {

            run->count++;

            run->cputime++;

            run->needtime--;

            if (run->needtime == 0)

            {

                run->state = 'F';

                InsertFinish(run);

                flag = 0;

            }

            else if (run->count == run->round)

            {

                run->state = 'W';

                run->count = 0;

                InsertTime(run);

                flag = 0;

            }

        }



        GetFirst();

    }

}

算法设计与实现(附流程图和源代码):

调试过程及实验结果(附截图): 

思考题:

如果设计一个基于优先级的时间片轮转调度算法,请给出你的设计思想和方案。进程ID;

设计基于优先级的时间片轮转调度算法思路:

在基于优先级的时间片轮转调度算法中,每个进程拥有一个优先级,进程按照优先级的高低进行调度。当处于运行状态的进程的时间片用完时,系统将根据优先级选择下一个进程执行。这种算法结合了优先级和时间片轮转两种调度策略,确保高优先级的进程能够更快地得到执行,同时也防止了低优先级的进程永远无法执行的情况。

基本设计思路:

  1. 优先级赋值: 每个进程创建时,根据其属性和历史行为确定一个优先级。这个优先级可以包括进程的重要性、紧急程度、资源需求等因素,以确保系统能够更好地满足业务需求。
  2. 时间片轮转: 每个进程被分配一个时间片,当时间片用完时,系统将根据进程的优先级选择下一个进程执行。如果就绪队列中有高优先级的进程,它将被选择执行;否则,根据时间片轮转策略选择下一个进程。
  3. 动态调整优先级: 系统可以根据进程的行为动态调整其优先级。例如,等待时间较长的进程可以提高其优先级,以避免饥饿现象。
  4. 就绪队列管理: 就绪队列按照优先级进行排序,确保高优先级的进程在队列头部,方便系统快速选择下一个执行的进程。
  5. 合理设置时间片: 时间片的大小需要根据系统的特点和需求进行合理设置。过大的时间片可能导致低优先级进程得不到及时执行,而过小的时间片可能导致上下文切换频繁。

实验小结:

  1. 优势和局限性: 基于优先级的时间片轮转调度算法能够更好地满足不同进程的优先级需求,提高系统的响应速度。然而,需要注意的是,如果高优先级的进程数量过多,低优先级的进程可能会受到影响,产生饥饿现象。
  2. 系统性能: 该调度算法需要合理权衡进程的优先级和时间片大小,以确保系统整体性能的优化。在实际应用中,需要根据具体的场景和要求进行调整和优化。
  3. 动态调整: 动态调整优先级是提高系统灵活性的关键。通过监控进程的行为,系统可以实时调整进程的优先级,以适应不断变化的工作负载。
  4. 综合考虑: 在设计调度算法时,需要综合考虑系统的特点、任务的性质以及用户需求,以找到最适合的调度策略。不同场景可能需要不同的优先级调度算法来实现最佳性能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1320237.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

超详细整理,Java接口自动化测试实战-rest-assured

1、关于rest-assured rest-assured 是一个能够简化测试rest服务的Java DSL&#xff0c;像ruby或者python一样的动态语言去测试和验证http服务。 基于java并且兼容了groovy动态语言的特性&#xff0c;使我们像写脚本语言一样去测试http服务。 例如&#xff1a;你的http服务&a…

范仲淹:文能治盛世,武可镇山河

北宋景佑元年&#xff08;公元1034&#xff09;年&#xff0c;范仲淹回乡祭拜范氏宗祠。在苏州祖宅住了几天后&#xff0c;范仲淹决定在苏州南园旁边买一块地&#xff0c;在此处盖一处房屋&#xff0c;待老迈时回乡居住。 按照家乡的风俗&#xff0c;在破土动工之前&#xff0c…

Note3---初阶二叉树~~

目录​​​​​​​ 前言&#x1f344; 1.树概念及结构☎️ 1.1 树的概念&#x1f384; 1.2 树的相关概念&#x1f99c; 1.2.1 部分概念的加深理解&#x1f43e; 1.2.2 树与非树&#x1fab4; 1.3 树的表示&#x1f38b; 1.4 树在实际中的运用&#xff08;表示文件系统…

软件试运行整体方案

一、 试运行目的 &#xff08;一&#xff09; 系统功能、性能与稳定性考核 &#xff08;二&#xff09; 系统在各种环境和工况条件下的工作稳定性和可靠性 &#xff08;三&#xff09; 检验系统实际应用效果和应用功能的完善 &#xff08;四&#xff09; 健全系统运行管理体…

Hadoop和Spark的区别

Hadoop 表达能力有限。磁盘IO开销大&#xff0c;延迟度高。任务和任务之间的衔接涉及IO开销。前一个任务完成之前其他任务无法完成&#xff0c;难以胜任复杂、多阶段的计算任务。 Spark Spark模型是对Mapreduce模型的改进&#xff0c;可以说没有HDFS、Mapreduce就没有Spark。…

架构简洁之道有感,谈谈软件组件聚合的张力

配图由腾讯混元助手生成 这篇文章介绍了软件架构设计中组件设计思想&#xff0c;围绕“组件间聚合的张力”这个有意思的角度&#xff0c;介绍了概念&#xff0c;并且结合架构设计示例对这个概念进行了进一步阐述。 组件聚合&#xff1f;张力&#xff1f;这标题&#xff0c;有种…

两位技术领导者的故事——英特尔和高通

对于科技行业来说&#xff0c;包括这样一个现实&#xff1a;上学、工作和娱乐实际上是未来生活的一部分。科技行业也面临着变革&#xff0c;行业内发生了几起重大收购和管理层变动。其中两个最具影响力的变化是英特尔和高通的换岗。具有讽刺意味的是&#xff0c;这两家公司在过…

UGUI 鼠标悬浮UI出现弹框,鼠标在图片边缘出现闪烁

1、背景&#xff1a;鼠标悬浮在UI上出现提示框 public class SpecialParam_list : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler {public void OnPointerEnter(PointerEventData eventData){TipBox.Instance.ShowBox(Input.mousePosition, value);}public void …

改进灰狼算法求解:考虑需求响应的风-光柴-储容量优化配置

目录 文章摘要&#xff1a; 亮点&#xff1a; 研究背景&#xff1a; 考虑需求相应的容量配置&#xff1a; 风、光、柴、储微电网模型&#xff1a; 储能配置模型&#xff1a; 改进的灰狼算法&#xff1a; 基于余弦规律变化的收敛因子 引入动态权重策略 运行效果&#…

长尾问题之LDAM

做法&代码&公式 step1: 全连接层的权重W和特征向量X都归一化,相乘 W * X P (得到各个类别的概率) # 定义权重&#xff0c;初始化 weight nn.Parameter(torch.FloatTensor(num_classes, num_features)) weight.data.uniform_(-1, 1).renorm_(2, 1, 1e-5).mul_(1e5)#…

初识迭代器(Iterator)——迭代器模式——迭代加深(后续更新...)

学习网页&#xff1a; Welcome to Python.orghttps://www.python.org/ 迭代器&#xff08;Iterator&#xff09; 迭代器是一个非常有用的Python特性&#xff0c;它允许我们遍历一个容器&#xff08;如列表、元组、字典、集合等&#xff09;的元素。迭代器提供了一种方法&…

02什么是CPU上下文切换

上⼀节&#xff0c; 讲了要怎么理解平均负载&#xff08; Load Average&#xff09; &#xff0c; 并⽤三个案例展示了不同场景下平均负载升⾼的分析⽅法。 这其中&#xff0c; 多个进程竞争 CPU 就是⼀个经常被我们忽视的问题。 1、CPU上下文切换的概念 我想你⼀定很好奇&am…

软件开发人员,参加各种行业技术大会有意义么?

参加行业技术大会对于软件开发人员来说&#xff0c;是一个获取新知识、拓展视野、结交同行的宝贵机会。 1、知识更新&#xff1a;技术大会通常涵盖最新的技术趋势和工具。对于软件开发人员来说&#xff0c;这是了解新技术并将其应用到日常工作中的好机会。 2、拓宽视野&#x…

遥测终端机RTU如何选型和配置?

随着物联网技术的不断发展&#xff0c;遥测终端机RTU在各个领域的应用越来越广泛。RTU作为数据采集、传输和处理的核心设备&#xff0c;对于确保数据的准确性和稳定性至关重要。那么&#xff0c;如何选型与配置遥测终端机RTU呢&#xff1f;本文将为您揭秘RTU的选型与配置技巧&a…

【ros2 control 机器人驱动开发】简单双关节机器人学习-example 1

【ros2 control 机器人驱动开发】简单双关节机器人学习-example 1 文章目录 前言一、RR机器人创建description pkg创建demos pkg 二、创建controller相关创建example pkg 三、测试运行总结 前言 本系列文件主要有以下目标和内容&#xff1a; 为系统、传感器和执行器创建 Har…

HTML中边框样式、内外边距、盒子模型尺寸计算(附代码图文示例)【详解】

Hi i,m JinXiang ⭐ 前言 ⭐ 本篇文章主要介绍HTML中边框样式、内外边距、盒子模型尺寸计算以及部分理论知识 &#x1f349;欢迎点赞 &#x1f44d; 收藏 ⭐留言评论 &#x1f4dd;私信必回哟&#x1f601; &#x1f349;博主收将持续更新学习记录获&#xff0c;友友们有任何问…

简单描述从输入网址到页面显示的过程

当用户输入网址并按下回车键后&#xff0c;浏览器会进行以下步骤&#xff1a; DNS 解析&#xff1a;浏览器会解析网址中的域名部分&#xff0c;提取出需要访问的目标域名。然后&#xff0c;它会向本地 DNS 服务器发送一个 DNS 查询请求&#xff0c;以获取该域名对应的 IP 地址。…

Trie 字典树(c++)(前缀)

题目链接&#xff1a;用户登录 题目&#xff1a; 样例&#xff1a; 输入 5 3 aaa aba aabbaa abbbbb cdd aabba abc abab 输出 Y N N 思路&#xff1a; 根据题目意思&#xff0c;要用到 Trie 字典树算法。 Trie 字典树&#xff0c;顾名思义&#xff0c;“字典”&#xff0…

竞赛保研 wifi指纹室内定位系统

简介 今天来介绍一下室内定位相关的原理以及实现方法; WIFI全称WirelessFidelity&#xff0c;在中文里又称作“行动热点”&#xff0c;是Wi-Fi联盟制造商的商标做为产品的品牌认证&#xff0c;是一个创建于IEEE 802.11标准的无线局域网技术。基于两套系统的密切相关&#xff…