4.22实验一:进程调度模拟算法

实验一:进程调度模拟算法

一、实验目的

进程调度是处理机管理的核心内容。本实验要求用高级语言编写模拟进程调度程序,以便加深理解有关进程控制快、进程队列等概念,并体会和了解优先数算法和时间片轮转算法的具体实施办法。

二、实验要求

1.设计进程控制块 PCB 的结构,通常应包括如下信息:进程名、进程优先数(或轮转时间片数)、进程已占用的CPU时间、进程到完成还需要的时间、进程的状态、当前队列指针等。

2.编写两种调度算法程序:

优先数调度算法程序

循环轮转调度算法程序

3.按要求输出结果。

提示和说明:

分别用两种调度算法对伍个进程进行调度。每个进程可有三种状态;执行状态(RUN)、就绪状态(READY包括等待状态)和完成状态(FINISH),并假定初始状态为就绪状态。

(一)进程控制块结构如下:

NAME--进程标示符

PRIO/ROUND--进程优先数/进程每次轮转的时间片数(设为常数2)

CPUTIME--进程累计占用CPU 的时间片数

NEEDTIMI--进程到完成还需要的时间片数

STATE--进程状态

NEXT--链指针

:

1.为了便于处理,程序中进程的的运行时间以时间片为单位进行计算:

2.各进程的优先数或轮转时间片数,以及进程运行时间片数的初值,均由用户在程序运行时给定。

(二)进程的就绪态和等待态均为链表结构,共有四个指针如下:

RUN--当前运行进程指针

READY--就需队列头指针

TAIL-- 就需队列尾指针

FINISH-完成队列头指针

(三)程序说明

1.在优先数算法中,进程优先数的初值设为:

50-NEEDTIME

每执行一次,优先数减1,CPU 时间片数加1,进程还需要的时间片数减1。在轮转法中,采用固定时间片单位(两个时间片为一个单位),进程每轮转一次,CPU时间片数加2,进程还需要的时间片数减2,并退出CPU,排到就绪队列尾,等待下一次调度。

2.程序的模块结构提示如下:

整个程序可由主程序和如下7个过程组成:

(1)INSERT1--在优先数算法中,将尚未完成的PCB 按优先数顺序插入到就绪队列

;(2)INSERT2--在轮转法中,将执行了一个时间片单位(为2),但尚未完成的进程的PCB,插到就绪队列的队尾;

(3)FIRSTIN--调度就绪队列的第一个进程投入运行;

(4)PRINT--显示每执行一次后所有进程的状态及有关信息,

(5)CREATE--创建新进程,并将它的PCB插入就绪队列;

(6)PRISCH--按优先数算法调度进程;

(7)ROUNDSCH--按时间片轮转法调度进程。

主程序定义 PCB 结构和其他有关变量。

(四)运行和显示

程序开始运行后,首先提示:请用户选择算法,输入进程名和相应的NEEDTIME值。每次显示结果均为如下5个字段:

name cputime needtime priority state

:

1.在 state 字段中,"R"代表执行态,"W"代表就绪(等待)态,"F"代表完成态2.应先显示"R"态的,再显示"W"态的,再显示"F"态的。

3.在"W"态中,以优先数高低或轮转顺序排队;在"F"态中,以完成先后顺序排队。

三、实验过程

1.准备

A. 查阅相关资料:

研究了进程调度的基本概念和原理

学习了优先数调度算法和时间片轮转算法的实现方式

查阅了C++中链表操作和指针使用的相关资料

参考了操作系统教材中关于进程控制块(PCB)的设计

  1. 初步编写程序:

设计了PCB结构体,包含进程名、优先数、CPU时间等字段

编写了两种调度算法的框架

实现了进程队列的基本操作(插入、删除等)

设计了状态显示函数

C. 准备测试数据:

进程名 需要时间片数

P1      5

P2      8

P3      5

2.上机调试

首先测试优先数调度算法

验证进程状态转换是否正确

检查队列操作是否正常

测试时间片轮转算法

比较两种算法的输出结果差异

调整时间片大小观察调度变化

3. 主要流程和源代码

   #include <iostream>

#include <vector>

#include <string>

#include <iomanip>

#include <cstdlib>  // 用于 system("pause")

using namespace std;

 

// 进程状态枚举

enum ProcessState {

    STATE_RUN,    // 执行态

    STATE_READY,  // 就绪态

    STATE_FINISH  // 完成态

};

 

// 进程控制块结构

struct PCB {

    string name;        // 进程名

    int prio;           // 优先数

    int round;          // 轮转时间片数

    int cpuTime;        // 已占用CPU时间

    int needTime;       // 还需要的时间

    ProcessState state; // 进程状态

    PCB* next;          // 链指针

    

    PCB(string n, int nt) : name(n), needTime(nt), cpuTime(0), state(STATE_READY), next(nullptr) {

        prio = 50 - needTime; // 初始优先数

        round = 2;            // 固定时间片单位

    }

};

 

// 全局指针

PCB* currentRun = nullptr;     // 当前运行进程

PCB* readyQueue = nullptr;     // 就绪队列头

PCB* tailQueue = nullptr;      // 就绪队列尾

PCB* finishQueue = nullptr;    // 完成队列头

 

// 函数声明

void createProcesses();

void printProcesses();

void prisch();          // 优先数调度

void roundsch();        // 轮转调度

void firstin();

void insert1(PCB* p);   // 优先数算法的插入

void insert2(PCB* p);   // 轮转算法的插入

 

int main() {

    int choice;

    cout << "请选择调度算法 (1-优先数, 2-时间片轮转): ";

    cin >> choice;

    

    // 创建进程

    createProcesses();

    

    // 根据选择执行不同调度算法

    if (choice == 1) {

        cout << "\n优先数调度算法:\n";

        while (currentRun != nullptr || readyQueue != nullptr) {

            prisch();

            printProcesses();

        }

    } else if (choice == 2) {

        cout << "\n时间片轮转调度算法:\n";

        while (currentRun != nullptr || readyQueue != nullptr) {

            roundsch();

            printProcesses();

        }

    } else {

        cout << "无效选择!" << endl;

    }

    

    // 打印最终完成队列

    cout << "\n所有进程已完成:\n";

    printProcesses();

    

    // 暂停程序,防止闪退

    cout << "\n按任意键继续..." << endl;

    cin.ignore();  // 忽略之前输入留下的换行符

    cin.get();     // 等待用户输入

    

    return 0;

}

 

// 创建进程

void createProcesses() {

    int numProcesses;

    cout << "输入进程数量: ";

    cin >> numProcesses;

    

    for (int i = 0; i < numProcesses; ++i) {

        string name;

        int needTime;

        cout << "输入进程名和需要的时间片数 (例如 P1 10): ";

        cin >> name >> needTime;

        

        PCB* p = new PCB(name, needTime);

        

        if (readyQueue == nullptr) {

            readyQueue = p;

            tailQueue = p;

        } else {

            tailQueue->next = p;

            tailQueue = p;

        }

    }

}

 

// 打印所有进程状态

void printProcesses() {

    cout << "\nname\tcputime\tneedtime\tpriority\tstate\n";

    cout << "---------------------------------------------\n";

    

    // 打印运行中的进程

    if (currentRun != nullptr) {

        cout << currentRun->name << "\t" << currentRun->cpuTime << "\t" << currentRun->needTime << "\t\t"

             << currentRun->prio << "\t\t" << "R" << endl;

    }

    

    // 打印就绪队列中的进程

    PCB* p = readyQueue;

    while (p != nullptr) {

        cout << p->name << "\t" << p->cpuTime << "\t" << p->needTime << "\t\t"

             << p->prio << "\t\t" << "W" << endl;

        p = p->next;

    }

    

    // 打印完成队列中的进程

    p = finishQueue;

    while (p != nullptr) {

        cout << p->name << "\t" << p->cpuTime << "\t" << p->needTime << "\t\t"

             << p->prio << "\t\t" << "F" << endl;

        p = p->next;

    }

    cout << endl;

}

 

// 优先数调度算法

void prisch() {

    if (currentRun != nullptr) {

        // 当前进程执行一个时间片

        currentRun->cpuTime++;

        currentRun->needTime--;

        currentRun->prio--;

        

        if (currentRun->needTime == 0) {

            // 进程完成

            currentRun->state = STATE_FINISH;

            currentRun->next = finishQueue;

            finishQueue = currentRun;

            currentRun = nullptr;

        } else {

            // 重新插入就绪队列

            PCB* temp = currentRun;

            currentRun = nullptr;

            insert1(temp);

        }

    }

    

    // 从就绪队列中选择优先数最高的进程运行

    if (currentRun == nullptr && readyQueue != nullptr) {

        firstin();

    }

}

 

// 轮转调度算法

void roundsch() {

    if (currentRun != nullptr) {

        // 当前进程执行一个时间片单位(2个时间片)

        currentRun->cpuTime += 2;

        currentRun->needTime -= 2;

        

        if (currentRun->needTime <= 0) {

            // 进程完成

            currentRun->needTime = 0;

            currentRun->state = STATE_FINISH;

            currentRun->next = finishQueue;

            finishQueue = currentRun;

            currentRun = nullptr;

        } else {

            // 重新插入就绪队列尾部

            PCB* temp = currentRun;

            currentRun = nullptr;

            insert2(temp);

        }

    }

    

    // 从就绪队列中选择下一个进程运行

    if (currentRun == nullptr && readyQueue != nullptr) {

        firstin();

    }

}

 

// 将就绪队列的第一个进程投入运行

void firstin() {

    currentRun = readyQueue;

    readyQueue = readyQueue->next;

    currentRun->next = nullptr;

    currentRun->state = STATE_RUN;

    

    // 更新队尾指针

    if (readyQueue == nullptr) {

        tailQueue = nullptr;

    }

}

 

// 优先数算法的插入(按优先数排序)

void insert1(PCB* p) {

    p->state = STATE_READY;

    

    if (readyQueue == nullptr) {

        readyQueue = p;

        tailQueue = p;

    } else {

        PCB* prev = nullptr;

        PCB* current = readyQueue;

        

        // 找到插入位置(按优先数从高到低)

        while (current != nullptr && current->prio >= p->prio) {

            prev = current;

            current = current->next;

        }

        

        if (prev == nullptr) {

            // 插入到队首

            p->next = readyQueue;

            readyQueue = p;

        } else {

            // 插入到中间或队尾

            prev->next = p;

            p->next = current;

            

            if (current == nullptr) {

                tailQueue = p;

            }

        }

    }

}

 

// 轮转算法的插入(插入到队尾)

void insert2(PCB* p) {

    p->state = STATE_READY;

    

    if (readyQueue == nullptr) {

        readyQueue = p;

        tailQueue = p;

    } else {

        tailQueue->next = p;

        tailQueue = p;

        p->next = nullptr;

    }

}

4.遇到的主要问题和解决方法

A. :程状态显示混乱,特别是完成队列的顺序不正确,重新设计状态显示逻辑

确保先显示运行态,再显示就绪态,最后显示完成态

在完成队列中按完成顺序排列进程

四、实验结果

 

 

五、实验总结

学到了操作系统进程调度的核心原理,深入理解了优先数算法和时间片轮转算法的设计思想与实现方式,对操作系统的进程管理机制有了更直观的认识。了解了进程控制块(PCB)的数据结构设计,掌握了通过链表管理进程队列的方法,熟悉了进程状态转换(就绪、运行、完成)的实现逻辑。握了使用C++实现复杂算法的技巧,提高了分析问题和设计解决方案的能力。

posted @ 2025-05-19 08:42    阅读(49)  评论(0)    收藏  举报