河南大学计算机操作系统实验5

来晚了!

分组:

实验室:

指导教师:

实验日期:

实验的准备阶段

(指导教师填写)

课程名称

计算机操作系统

实验名称

处理处理机调度算法

实验目的

(1)理解处理机算法的工作原理。

(2)掌握调度算法的实现、进程的状态以及状态转换。

实验内容

时间片轮转算法(模拟)

1、用到的数据结构

/* PCB */

struct PCB         

{

        pid_t pid;//进程PID

        int state; //状态信息,1表示正在运行,0表示暂停,-1表示结束

        unsigned long runned_time;//已运行时间

        unsigned long need_running_time;//剩余运行时间

};

/* PCB集合 */

struct PCB pcb[TOTAL];  //PCB集合

2、算法思路

算法实现分主函数(main)和分派函数(Dispatch)。

(1)其中主函数(main)的核心功能为:

实现6个子进程的创建和子进程PCB的初始化。对子进程PCB初始化时,状态设为0,运行时间由随机数产生。子进程创建后,就通过信号SIGSTOP让它处于暂停状态,当被分派函数(Dispatch)选中后,才能继续执行,输出子进程**正在执行的信息。

同时要在主程序里设置定时器,定时器的时间间隔为时间片长度,时间片到,就调用分派函数(Dispatch)重新选派程序。

  1. 分配函数的核心功能:

将正在执行的子进程暂停,状态变为0,修改已运行时间和剩余运行时间。

如果该子进程剩余时间小于零,说明执行完毕,PCB状态改为-1,结束该子进程。

如果所有子进程都都结束,则程序结束。

重新选择下一个子进程,状态变为1,输出该子进程的已运行时间和剩余运行时间,让该子进程恢复运行。

实验类型

(打R)

☑验证性    □演示性     ☑设计性      □综合性

实验的重点、难点

时间片轮转调度算法的实现

实验环境

VMWare、RedHat Linux

实验的实施阶段

实验步骤及实验结果

实验环境:centos 7

代码实现:

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <signal.h>

#include <sys/types.h>

#include <sys/time.h>

#define TOTAL 6

#define TIME_QUANTUM 3

struct PCB {

    pid_t pid;

    int state;

    unsigned long runned_time;

    unsigned long need_running_time;

};

struct PCB pcb[TOTAL];

void Dispatch(int signum) {

    int i;

    for (i = 0; i < TOTAL; ++i) {

        if (pcb[i].state == 1) {

            printf("进程 %d 正在运行。\n", pcb[i].pid);

            pcb[i].runned_time += TIME_QUANTUM;

            pcb[i].need_running_time -= TIME_QUANTUM;

            if (pcb[i].need_running_time <= 0) {

                printf("进程 %d 完成。\n", pcb[i].pid);

                pcb[i].state = -1;

            } else {

                printf("进程 %d - 已运行时间:%lu,剩余运行时间:%lu\n", pcb[i].pid, pcb[i].runned_time, pcb[i].need_running_time);

                pcb[i].state = 0;

            }

            int next = (i + 1) % TOTAL;

            while (pcb[next].state == -1) {

                next = (next + 1) % TOTAL;

            }

            printf("选择下一个进程:%d\n", pcb[next].pid);

            pcb[next].state = 1;

            kill(pcb[next].pid, SIGCONT);

            break;

        }

    }

    if (i == TOTAL) {

        printf("所有进程完成。\n");

        exit(0);

    }

}

int main() {

    int i;

    struct sigaction sa;

    sa.sa_handler = Dispatch;

    sa.sa_flags = 0;

    sigemptyset(&sa.sa_mask);

    sigaction(SIGALRM, &sa, NULL);

    srand(time(NULL));

    for (i = 0; i < TOTAL; ++i) {

        pcb[i].pid = fork();

        if (pcb[i].pid == 0) {  // 子进程

            pcb[i].state = 0;

            pcb[i].runned_time = 0;

            pcb[i].need_running_time = rand() % 20 + 1; // 随机运行时间

            signal(SIGSTOP, SIG_IGN); // 忽略子进程的 SIGSTOP 信号

            while (1); // 子进程保持运行直到被调度选择

        } else if (pcb[i].pid > 0) { // 父进程

            pcb[i].state = 0;

            kill(pcb[i].pid, SIGSTOP); // 暂停子进程

        }

    }

    // 设置定时器

    struct itimerval timer;

    timer.it_interval.tv_sec = TIME_QUANTUM;

    timer.it_interval.tv_usec = 0;

    timer.it_value.tv_sec = TIME_QUANTUM;

    timer.it_value.tv_usec = 0;

    setitimer(ITIMER_REAL, &timer, NULL);

    while (1); // 父进程持续运行直到所有子进程完成

    return 0;

}

运行结果:

实验结果的处理阶段

实验结果的分析与总结

我通过观察和分析调度算法的执行情况以及子进程的行为,深入了解时间片轮转调度算法的工作原理和特性,并对系统调度器的行为有更清晰的认识。通过这个实验,我进行了以下操作:

  1. 我观察了调度算法的执行情况。通过观察每个进程的运行情况,了解了时间片轮转调度算法如何按照时间片分配CPU时间给各个进程。
  2. 我了解了时间片大小对程序执行的影响。我尝试改变时间片大小,观察这一操作对程序整体执行效率和响应时间的影响。
  3. 我了解了了解子进程的创建过程、运行状态以及被暂停和恢复的机制。

我了解了进程的切换和调度,我关注进程之间的切换过程,观察被选中的下一个进程是如何被调度执行的,以及当所有进程执行完毕时,程序是如何结束的。

4. 我明白了定时器的作用,观察了调度器在执行过程中的效率,如进程切换的次数和开销。

  • 23
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值