现在的位置: 首页 > 综合 > 正文

多级反馈队列进程调度算法 实验报告

2013年10月01日 ⁄ 综合 ⁄ 共 6426字 ⁄ 字号 评论关闭

实验课程:操作系统 

实验名称:进程调度的设计与实现     (综合实验)

第一部分 实验内容

1.实验目标

1、 综合应用下列知识点设计并实现操作系统的进程调度:邻接表,布尔数组,非阻塞输入,图形用户界面GUI,进程控制块,进程状态转换,多级反馈队列进程调度算法

2、 加深理解操作系统进程调度的过程。

3、 加深理解多级反馈队列进程调度算法。

2. 实验任务

1、 用一种熟悉的语言,如CPASCALC++等,编制程序。

2、 采用多级反馈队列调度算法进行进程调度。

3. 实验设备及环境

PCC/C++编程语言

4. 实验主要步骤

(1) 根据实验目标,明确实验的具体任务;

(2) 编写程序实现进程调度算法;

(3) 设计实验数据并运行程序、记录运行的结果;

(4) 分析实验结果;

(5) 实验后的心得体会。

第二部分 问题及算法

1. 问题描述

(1) 采用一种熟悉的语言,如CPASCALC++等,编制程序。

(2) 采用多级反馈队列调度算法进行进程调度。

(3) 每个进程对应一个PCB。在PCB中包括进程标识符pid、进程的状态标识status、进程优先级priority、进程的队列指针next和表示进程生命周期的数据项life(在实际系统中不包括该项)。

(4) 创建进程时即创建一个PCB,各个进程的pid都是唯一的,pid是在1100范围内的一个整数。可以创建一个下标为1100的布尔数组,“真”表示下标对应的进程标识号是空闲的,“假”表示下标对应的进程标识号已分配给某个进程。

(5) 进程状态status的取值为“就绪ready”或“运行run”,刚创建时,状态为“ready”。被进程调度程序选中后变为“run”。

(6) 进程优先级priority049范围内的一个随机整数。

(7) 进程生命周期life15范围内的一个随机整数。

(8) 初始化时,创建一个邻接表,包含50个就绪队列,各就绪队列的进程优先级priority分别是049

(9) 为了模拟用户动态提交任务的过程,要求动态创建进程。进入进程调度循环后,每次按ctrl+f即动态创建一个进程,然后将该PCB插入就绪队列中。按ctrl+q退出进程调度循环。

(10) 在进程调度循环中,每次选择优先级最大的就绪进程来执行。将其状态从就绪变为运行,通过延时一段时间来模拟该进程执行一个时间片的过程,然后优先级减半,生命周期减一。设计图形用户界面GUI,在窗口中显示该进程和其他所有进程的PCB内容。如果将该运行进程的生命周期不为0,则重新把它变为就绪状态,插入就绪队列中;否则该进程执行完成,撤消其PCB。以上为一次进程调度循环。

(11) 在上机实现该程序之后,要求写出实验报告,其中包括实验名称、实验目的、实验内容、程序的主要流程图、实验心得和主要源程序清单等。

2. 多级反馈队列进程调度算法的一般思路

   (1) 进程在进入待调度的队列等待时,首先进入优先级最高的Q1等待。

   (2) 首先调度优先级高的队列中的进程。若高优先级中队列中已没有调度的进程,则调度次优先级队列中的进程。例如:Q1,Q2,Q3三个队列,只有在Q1中没有进程等待时才去调度Q2,同理,只有Q1,Q2都为空时才会去调度Q3

   (3) 对于同一个队列中的各个进程,按照时间片轮转法调度。比如Q1队列的时间片为N,那么Q1中的作业在经历了N个时间片后若还没有完成,则进入Q2队列等待,若Q2的时间片用完后作业还不能完成,一直进入下一级队列,直至完成。

   (4) 在低优先级的队列中的进程在运行时,又有新到达的作业,那么在运行完这个时间片后,CPU马上分配给新到达的作业(抢占式)。

3. 算法实现的关键点

队列的切换和优先级的变化。

第三部分 实验结果与分析

1. 实验数据及结果

实验数据为随机数据,所以结果也为随机值,故见下文

2. 实验分析及结论

由于不会关于GUI的相关程序,所以做不了GUI界面,故而比较难看。

第四部分 心得与展望

1. 自我评价及心得体会

看起来很简单,但是做起来很复杂,需要很长一段时间。

2.  展望

以后有时间要学GUI编程。

第五部分 附录

1. 主要界面

2. 源程序

/**

made by FrankieCCT

time:2013.5.19 7:13

main.cpp

**/

#include "myQueue.h"

int main()

{

    char chioce;

    PCB *tmp_pcb;

    int i;

    int flag = 0;

    fill(&pid_queue[0],&pid_queue[100],true);

    while (1)

    {

        menu();

        cin >> chioce;

        switch (chioce)

        {

        case 'y':

        case 'Y':

            tmp_pcb = get_a_random_ready_PCB();

            insert_pcb(tmp_pcb, tmp_pcb->priority);

            break;

        case 'n':

        case 'N':

            break;

        default:

            puts("illegal!");

            system("pause");

            system("cls");

            continue;

            break;

        }

            for (i = 49; i > -1; i--)

            {

                if (p_queue[i].first_task != NULL)

                {

                    puts("上一时间片运行情况:");

                    tmp_pcb = p_queue[i].first_task;

                    tmp_pcb->status = RUN_PCB;

                    cout << "pid: " << p_queue[i].first_task->pid

                        << "\t的进程被选中,将之状态变为run, 生命周期由"

                        << p_queue[i].first_task->life--;

                    cout << "变为" << p_queue[i].first_task->life << endl;

                    p_queue[i].first_task->status = READY_PCB;

                    if (p_queue[i].first_task->life > 0)

                    {

                        cout << "生命周期不为0,将之状态变为ready,优先级由"

                            << tmp_pcb->priority;

                        cout << "变为" <<  tmp_pcb->priority/2

                            <<"后插入对应队列。" << endl;

                        tmp_pcb->priority /= 2;

                        insert_pcb(tmp_pcb, tmp_pcb->priority);

                    }

                    else if (p_queue[i].first_task->life == 0)

                    {

                        cout << "生命周期变成0,所以进程结束,该PCB被撤销." << endl;

                        pid_queue[p_queue[i].first_task->pid] = true;

                    }

                    p_queue[i].first_task = p_queue[i].first_task->next;

                    break;

                }

            }

        if (i == -1)

        {

            puts("all complete!");

        }

        puts("现在线程情况:");

        for (i = 49; i > -1; i--)

        {

            if (p_queue[i].first_task != NULL)

            {

                cout << "queue " << i << ": " << endl;

                cout << "pid: " << p_queue[i].first_task->pid

                     << "\tlife: " << p_queue[i].first_task->life << endl;

                tmp_pcb = p_queue[i].first_task->next;

                while (tmp_pcb != NULL)

                {

                    cout << "pid: " <<tmp_pcb->pid

                         << "\tlife: " << tmp_pcb->life << endl;

                    tmp_pcb = tmp_pcb->next;

                }

            }

        }

    }

    return 0;

}

/**

made by FrankieCCT

time:2013.5.19 7:13

myQueue.h

**/

#ifndef MYQUEUE_H_INCLUDED

#define MYQUEUE_H_INCLUDED

#include <iostream>

using namespace std;

#include <cstdio>

#include <cmath>

#include <ctime>

#include <cstdlib>

#define MAX_PID_NUM 101

#define MAX_PCB_NUM 50

#define READY_PCB 1

#define RUN_PCB 2

struct PCB;

int get_available_pid();

void menu();

PCB *get_a_random_ready_PCB();

bool pid_queue[MAX_PID_NUM];

struct PCB

{

    int pid;

    int status;

    int priority;

    PCB *next;

    int life;

    PCB()

    {

        srand(time(0));

        status = READY_PCB;

        pid = get_available_pid();

        if (pid == -1)

        {

            puts("full pid queue!");

            system("pause");

            abort();

        }

        else

        {

            pid_queue[pid] = false;

        }

        next = NULL;

        priority = rand() % 49 + 1;

        life = rand() % 5 + 1;

    }

    PCB(const PCB&pcb)

    {

        status = pcb.status;

        pid = pcb.pid;

        next = pcb.next;

        priority = pcb.priority;

        life = pcb.life;

    }

};

struct PCB_queue

{

    PCB *first_task;

    PCB_queue()

    {

        first_task = NULL;

    }

};

int get_available_pid()

{

    for (int i = 0; i < 101; i++)

        if (pid_queue[i])

            return i;

    return -1;

}

void menu()

{

    puts("是否新建进程?(Y/N");

}

PCB *get_a_random_ready_PCB()

{

    PCB *a_pcb = new PCB();

    cout << "一个pid" << a_pcb->pid

        << ",生命周期为" << a_pcb->life

        << ", 优先级为" << a_pcb->priority

        << "的进程被创建。" << endl;

    return a_pcb;

}

PCB_queue p_queue[MAX_PCB_NUM];

void insert_pcb(PCB *tmp_pcb, int i)

{

    PCB *tmp_pcb_other;

    if (p_queue[i].first_task == NULL)

    {

        p_queue[i].first_task = tmp_pcb;

        p_queue[i].first_task->next = NULL;

    }

    else

    {

        tmp_pcb_other = p_queue[i].first_task;

        while (tmp_pcb_other->next != NULL)

        {

            tmp_pcb_other = tmp_pcb_other->next;

        }

        tmp_pcb_other->next = tmp_pcb;

        tmp_pcb_other->next->next = NULL;

    }

}

#endif // MYQUEUE_H_INCLUDED

参考文献

l 《操作系统教程》谢旭东,朱明华,张练兴,李宏伟等,机械工业出版社,2013年

抱歉!评论已关闭.