操作系统实验一

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

一、实验目的

通过编写模拟进程调度程序,加深对进程控制块(PCB)、进程队列等概念的理解,掌握优先级调度算法和时间片轮转算法的实现方法,并体会它们在操作系统中的实际应用。

二、实验要求

1.设计进程控制块的结构,包含进程名、优先级、CPU时间、剩余时间、状态等信息。

2.实现优先级调度算法和轮转调度算法。

3.输出每次调度后各进程的状态及相关信息。

三、实验过程

1.准备

A. 查阅相关资料:

B. 初步编写程序:

C. 准备测试数据:

D. …….

2.上机调试

A.Visual Studio和GCC编译器中进行调试,逐步排除错误并完善代码逻辑。

B.测试了不同数量和属性的进程,确保输出符合预期。

3. 主要流程和源代码

程序流程如下:

1.定义 PCB 结构;

2.实现插入函数,按优先级或轮转顺序插入;

3.实现优先级调度算法;

4.实现时间片轮转调度算法;

5.主程序中获取用户输入并调用相应的调度算法。

 

源代码:

#include <iostream>

#include <iomanip>

#include <vector>

#include <algorithm>

using namespace std;

// 进程状态枚举

enum State { RUN_STATE, READY_STATE, FINISH_STATE };

// 进程控制块结构

struct PCB {

    string name;        // 进程名

    int priority;       // 优先数

    int cputime;        // 已占用CPU时间

    int needtime;       // 还需时间

    State state;        // 进程状态

    PCB* next;          // 链指针

    

    PCB(string n, int nt) : name(n), needtime(nt), cputime(0), state(READY_STATE), next(NULL) {

        priority = 50 - needtime; // 初始优先数

    }

};

 

// 全局指针

PCB* RUN = NULL;       // 当前运行进程

PCB* READY = NULL;     // 就绪队列头

PCB* TAIL = NULL;      // 就绪队列尾

PCB* FINISH = NULL;    // 完成队列头

 

// 打印进程信息

void PRINT() {

    cout << left << setw(10) << "name"

         << setw(10) << "cputime"

         << setw(10) << "needtime"

         << setw(10) << "priority"

         << setw(10) << "state" << endl;

    

    // 先打印运行态进程

    if (RUN) {

        cout << left << setw(10) << RUN->name

             << setw(10) << RUN->cputime

             << setw(10) << RUN->needtime

             << setw(10) << RUN->priority

             << setw(10) << "R" << endl;

    }

    

    // 打印就绪态进程

    PCB* p = READY;

    while (p) {

        cout << left << setw(10) << p->name

             << setw(10) << p->cputime

             << setw(10) << p->needtime

             << setw(10) << p->priority

             << setw(10) << "W" << endl;

        p = p->next;

    }

    

    // 打印完成态进程

    p = FINISH;

    while (p) {

        cout << left << setw(10) << p->name

             << setw(10) << p->cputime

             << setw(10) << p->needtime

             << setw(10) << p->priority

             << setw(10) << "F" << endl;

        p = p->next;

    }

    cout << "----------------------------------" << endl;

}

 

// 优先数算法插入就绪队列

void INSERT1(PCB* process) {

    if (!READY) {

        READY = TAIL = process;

        return;

    }

    

    PCB *prev = NULL, *curr = READY;

    while (curr && curr->priority >= process->priority) {

        prev = curr;

        curr = curr->next;

    }

    

    if (!prev) {

        process->next = READY;

        READY = process;

    } else {

        prev->next = process;

        process->next = curr;

        if (!curr) TAIL = process;

    }

}

 

// 轮转法插入就绪队列尾

void INSERT2(PCB* process) {

    if (!READY) {

        READY = TAIL = process;

    } else {

        TAIL->next = process;

        TAIL = process;

    }

    process->next = NULL;

}

 

// 从就绪队列首部取出进程

PCB* FIRSTIN() {

    if (!READY) return NULL;

    

    PCB* p = READY;

    READY = READY->next;

    if (!READY) TAIL = NULL;

    p->next = NULL;

    return p;

}

 

// 创建进程并插入就绪队列

void CREATE(int alg) {

    string name;

    int needtime;

    cout << "输入进程名和需要的时间片: ";

    cin >> name >> needtime;

    

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

    if (alg == 1) INSERT1(p);

    else INSERT2(p);

}

 

// 将进程加入完成队列

void addToFinish(PCB* p) {

    p->state = FINISH_STATE;

    p->next = FINISH;

    FINISH = p;

}

 

// 优先数调度算法

void PRISCH() {

    RUN = FIRSTIN();

    if (!RUN) return;

    

    RUN->state = RUN_STATE;

    cout << "运行进程: " << RUN->name << endl;

    

    // 执行一个时间片

    RUN->cputime++;

    RUN->needtime--;

    RUN->priority--;

    

    if (RUN->needtime <= 0) {

        cout << RUN->name << " 完成!" << endl;

        addToFinish(RUN);

    } else {

        RUN->state = READY_STATE;

        INSERT1(RUN);

    }

    RUN = NULL;

}

 

// 时间片轮转调度算法

void ROUNDSCH() {

    RUN = FIRSTIN();

    if (!RUN) return;

    

    RUN->state = RUN_STATE;

    cout << "运行进程: " << RUN->name << endl;

    

    // 执行一个时间片单位(2个时间片)

    int slice = min(2, RUN->needtime);

    RUN->cputime += slice;

    RUN->needtime -= slice;

    

    if (RUN->needtime <= 0) {

        cout << RUN->name << " 完成!" << endl;

        addToFinish(RUN);

    } else {

        RUN->state = READY_STATE;

        INSERT2(RUN);

    }

    RUN = NULL;

}

 

// 释放内存

void cleanup() {

    PCB* p = FINISH;

    while (p) {

        PCB* temp = p;

        p = p->next;

        delete temp;

    }

}

 

int main() {

    int alg, count;

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

    cin >> alg;

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

    cin >> count;

    

    // 创建进程

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

        CREATE(alg);

    }

    

    // 执行调度

    while (READY) {

        if (alg == 1) PRISCH();

        else ROUNDSCH();

        PRINT();

    }

    

    cleanup();

    return 0;

}

 

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

A. :进程状态更新错误。

解决:检查状态转换逻辑,确保每次调度后正确更新PCB的state字段。

B. :队列插入顺序混乱。

解决:在INSERT1和INSERT2函数中严格按优先级或轮转规则排序。

四、实验结果

     

 

 

 

 

五、实验总结

通过本次进程调度模拟算法实验,我对操作系统中进程管理的核心机制有了更深刻的理解与实践体会。在实验过程中,从设计进程控制块(PCB)结构到实现优先级调度算法和时间片轮转算法,每个环节都让我将理论知识与编程实践紧密结合。

在编程实践上,本次实验极大地提升了我的代码设计与调试能力。在实现插入函数时,需要根据不同算法规则调整进程在就绪队列中的插入顺序,这锻炼了我对数据结构(链表)的灵活运用能力。在调试过程中,针对进程状态更新错误和队列插入顺序混乱等问题,通过逐步排查代码逻辑、添加调试输出语句,最终成功解决问题,这让我掌握了高效的调试技巧,也培养了严谨的编程思维。

从实验收获来看,我不仅掌握了两种经典进程调度算法的实现方法,更体会到操作系统底层设计的复杂性与精妙之处。同时,实验过程也让我意识到团队协作与技术交流的重要性,通过与同学讨论问题、分享解决方案,拓宽了自己的思路。

posted @ 2025-06-12 17:26  chrisrmas、  阅读(8)  评论(0)    收藏  举报