操作系统实验四——进程调度

本文介绍了一个使用C语言实现的操作系统进程调度模拟程序。该程序通过动态优先级法对进程进行调度,展示了如何创建进程控制块(PCB),并根据不同算法构建进程队列。程序能够按照设定的参数运行,并在屏幕上交替显示就绪队列和完成队列的信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实验任务
设计一个程序,根据不同的调度算法模拟操作系统对进程的调度。
动态优先级法
1、 设计进程控制块PBC表结构,分别适用优先数调度算法
2、 PBC结构通常包括以下信息:进程名、进程优先数、轮转时间片、进程的CPU时间,进程状态等。根据调度算法不同,PCB结构可作适当的调整。
3、 建立进程队列。对不同的算法编制不同的入链程序。
程序要求达到的运行效果:在设置好进程数量、调度算法后,系统能按设定的参数运行,并在屏幕上交替显示就绪队列和完成队列的进程名等信息。

Windows环境代码如下(解释很详细)

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct node {
    char name[20];     /*进程的名字*/
    int prio;          /*进程的优先级*/
    //int cputime;     /*CPU执行时间*/
    int needtime;      /*进程执行所需要的时间*/
    char state;        /*进程的状态,W--就绪态,R--执行态,F--完成态*/
    struct node *next;/*链表指针*/
}PCB;

PCB*ready=NULL,*run=NULL,*finish=NULL;/*定义三个队列,就绪队列,执行队列和完成队列*/
int num;
void GetFirst();       /*从就绪队列取得第一个节点*/
void Output();         /*输出队列信息*/
void InsertPrio(PCB*in);/*创建优先级队列,规定优先数越小,优先级越高*/
void InsertTime(PCB*in);/*时间片队列*/
void InsertFinish(PCB*in);/*时间片队列*/
void PrioCreate();     /*优先级输入函数*/
//void TimeCreate();   /*时间片输入函数*/
void Priority();       /*按照优先级调度*/
//void RoundRun();     /*时间片轮转调度*/
int main() {
    printf("优先级调度算法\n");
    printf("please input the number of processes:");
    scanf("%d",&num);
    PrioCreate();
    Priority();
    Output();
    return 0;
}
/*取得第一个就绪队列节点*/
void GetFirst(){
    run=ready;
    if(ready!=NULL){
        run->state='R';
        ready=ready->next;
        run->next=NULL;
    }
}
void Output()/*输出队列信息*/
{
    PCB*p;
    p=ready;
    printf("pcb_name\tpriority\tneed_time\tpro_state\n");
    while(p!=NULL){
        printf("%s\t%d\t%d\t\t%c\t\n",p->name,p->prio,p->needtime,p->state);
        p=p->next;
    }
    p=finish;
    while(p!=NULL){
        printf("%s\t%d\t%d\t\t%c\t\n",p->name,p->prio,p->needtime,p->state);
        p=p->next;
    }
    p=run;
    while(p!=NULL){
        printf("%s\t    %d\t    %d\t    \t%c    \t\n",p->name,p->prio,p->needtime,p->state);
        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 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("please input process_name,need_time,priority:\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));
        getchar();
        scanf("%d",&(tmp->prio));
        //tmp->cputime=0;
        tmp->state='W';
        //tmp->prio=20-tmp->needtime;
        /*设置其优先级,需要的时间越多,优先级越低*/
        InsertPrio(tmp);/*按照优先级从高到低,插入到就绪队列*/
    }
}
void Priority()/*按照优先级调度,每次执行一个时间片*/
{
    int flag=1;
    GetFirst();
    while(run!=NULL)/*当就绪队列不为空时,则调度进程如执行队列执行*/
    {
        Output();/*输出每次调度过程中各个节点的状态*/
        while(flag){
            run->prio-=3;/*优先级减去三*/
            run->needtime--;/*进程执行完成的剩余时间减一*/
            if(run->needtime == 0)/*如果进程执行完毕,将进程状态置为F,将其插入到完成队列*/
            {
                run->state='F';
                InsertFinish(run);
                flag=0;
            }
            else/*将进程状态置为W,入就绪队列*/
            {
                run->state='W';
                InsertPrio(run);
                flag=0;
            }
        }
        flag=1;
        GetFirst();/*继续取就绪队列队头进程进入执行队列*/
    }
}
实验进程调度 编写并调试一个模拟进程调度程序,采用“短进程优先”调度算法对五个进程进行调度。以加深对进程的概念及进程调度算法的理解. 下面是采用动态优先数的调度程序,可作参考。  例题: 设计一个有 N个进程共行的进程调度程序。   进程调度算法:采用最高优先数优先的调度算法(即把处理机分配给优先数最高的进程)和先来先服务算法。   每个进程有一个进程控制块( PCB)表示。进程控制块可以包含如下信息:进程名、优先数、到达时间、需要运行时间、已用CPU时间、进程状态等等。   进程的优先数及需要的运行时间可以事先人为地指定(也可以由随机数产生)。进程的到达时间为进程输入的时间。   进程的运行时间以时间片为单位进行计算。   每个进程的状态可以是就绪 W(Wait)、运行R(Run)、或完成F(Finish)三种状态之一。   就绪进程获得 CPU后都只能运行一个时间片。用已占用CPU时间加1来表示。   如果运行一个时间片后,进程的已占用 CPU时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时应将进程的优先数减1(即降低一级),然后把它插入就绪队列等待CPU。   每进行一次调度程序都打印一次运行进程、就绪队列、以及各个进程的 PCB,以便进行检查。重复以上过程,直到所要进程都完成为止。实验二 作业调度 一、实验目的:用高级语言编写和调试一个或多个作业调度模拟程序,以加深对作业调度算法的理解。 二、实验内容: 1.写并调试一个单道处理系统的作业等待模拟程序。 2.作业等待算法:分别采用先来先服务(FCFS)、响应比高者优先(HRN)的调度算法。 3.由于在单道批处理系统中,作业一投入运行,它就占有计算机的一切资源直到作业完成为止,因此调度作业时不必考虑它所需要的资源是否得到满足,它所占用的 CPU时限等因素。 4.每个作业由一个作业控制块JCB表示,JCB可以包含如下信息:作业名、提交时间、所需的运行时间、所需的资源、作业状态、链指针等等。作业的状态可以是等待W(Wait)、运行R(Run)和完成F(Finish)三种状态之一。每个作业的最初状态总是等待W。 5.对每种调度算法都要求打印每个作业开始运行时刻、完成时刻、周转时间、带权周转时间,以及这组作业的平均周转时间及带权平均周转时间。 三、思考:比较各种算法的优缺点。 实验三 动态分区分配方式的模拟 1、实验目的:了解动态分区分配方式中的数据结构和分配算法,并进一步加深对动态分区存储管理方式及其实现过程的理解 2、实验内容: (1)用C语言分别实现采用首次适应算法和最佳适应算法的动态分区分配过程和回收过程。其中,空闲分区通过空闲分区链(表)来管理;在进行内存分配时,系统优先使用空闲区低端的空间。 (2)假设初始状态下,可用的内存空间为640KB,并有下列的请求序列: •作业1申请130KB •作业2申请60KB •作业3申请100KB •作业2释放60KB •作业4申请200KB •作业3释放100KB •作业1释放130KB •作业5申请140KB •作业6申请60KB •作业7申请50KB •作业8申请60KB 请分别采用首次适应算法和最佳适应算法进行内存的分配和回收,要求每次分配和回收后显示出空闲内存分区链的情况。 3、思考:讨论各种分配算法的特点。
3.4 独立实验 设有两个并发执行的父子进程,不断循环输出各自号、优先数和调度策略。 设有两个并发执行的父子进程,不断循环输出各自号、优先数和调度策略。 设有两个并发执行的父子进程,不断循环输出各自号、优先数和调度策略。 设有两个并发执行的父子进程,不断循环输出各自号、优先数和调度策略。 设有两个并发执行的父子进程,不断循环输出各自号、优先数和调度策略。 设有两个并发执行的父子进程,不断循环输出各自号、优先数和调度策略。 设有两个并发执行的父子进程,不断循环输出各自号、优先数和调度策略。 设有两个并发执行的父子进程,不断循环输出各自号、优先数和调度策略。 设有两个并发执行的父子进程,不断循环输出各自号、优先数和调度策略。 设有两个并发执行的父子进程,不断循环输出各自号、优先数和调度策略。 设有两个并发执行的父子进程,不断循环输出各自号、优先数和调度策略。 设有两个并发执行的父子进程,不断循环输出各自号、优先数和调度策略。 设有两个并发执行的父子进程,不断循环输出各自号、优先数和调度策略。 设有两个并发执行的父子进程,不断循环输出各自号、优先数和调度策略。 设有两个并发执行的父子进程,不断循环输出各自号、优先数和调度策略。 设有两个并发执行的父子进程,不断循环输出各自号、优先数和调度策略。 设有两个并发执行的父子进程,不断循环输出各自号、优先数和调度策略。 进程初始调度策略均为系统默认和优先级。当 进程初始调度策略均为系统默认和优先级。当 进程初始调度策略均为系统默认和优先级。当 进程初始调度策略均为系统默认和优先级。当 进程初始调度策略均为系统默认和优先级。当 进程初始调度策略均为系统默认和优先级。当 进程初始调度策略均为系统默认和优先级。当 进程初始调度策略均为系统默认和优先级。当 进程初始调度策略均为系统默认和优先级。当 进程初始调度策略均为系统默认和优先级。当 进程初始调度策略均为系统默认和优先级。当 进程初始调度策略均为系统默认和优先级。当 父进程收到 进程收到 由键盘 由键盘 Ctrl+CCtrl+C Ctrl+C 发 出的 SIGINT SIGINTSIGINTSIGINTSIGINT信号时会自动将其优先数加 信号时会自动将其优先数加 信号时会自动将其优先数加 信号时会自动将其优先数加 信号时会自动将其优先数加 信号时会自动将其优先数加 信号时会自动将其优先数加 1,子进程进程 收到 由键盘 由键盘 Ctrl+ZCtrl+Z Ctrl+Z发出的 SIG SIGTSTP STP信号时会自动将其优先数减 信号时会自动将其优先数减 信号时会自动将其优先数减 信号时会自动将其优先数减 信号时会自动将其优先数减 信号时会自动将其优先数减 信号时会自动将其优先数减 1。 请编程实现以上功能。 请编程实现以上功能。 请编程实现以上功能。 请编程实现以上功能。 请编程实现以上功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值