操作系统实验python

操作系统实验

1、将一组进程分为4类,如图所示,各类进程之间采用优先级调度,各类进程内部采用时间片轮转调度。请设计程序实现P1、P2、P3、P4、P5、P6、P7、P8进程的调度。

在这里插入图片描述

具体做法是调度程序每次把CPU分配给当前最高优先级进程使用一个时间片。 当这个时间片结束时,强迫该进程让出处理器,进行下一轮优先级调度,直至就绪队列中所有进程都运行完成为止。

代码:

import time


class PCB:

    def __init__(self, priority, hold_time, come_time, name, status=0):
        """
        :param status: PCB 进程控制块状态:0为等待态, 1为执行态
        :param priority: 优先级别:0, 1, 2, 3, 4, ...
        :param hold_time: 处理机占用时间
        :param come_time: 进入进程队列时间
        """
        self.status = status
        self.priority = priority
        self.hold_time = hold_time
        self.come_time = come_time
        self.progress_name = name

    def __str__(self):
        return str(self.progress_name) + "\t" + str(self.priority) + "\t\t\t" + \
               str(self.come_time) + "\t\t\t" + str(self.hold_time) + "\t\t\t\t" + \
               str('就绪态' if self.status == 0 else '执行态')


class PriorityAlgorithm:

    def __init__(self):
        self.progresses = []
        self.__progresses_in()
        self.max_index = -1

    def __progresses_in(self):
        self.progresses.append(PCB(4, 5, 0, "P1"))
        self.progresses.append(PCB(4, 3, 0, "P2"))
        self.progresses.append(PCB(4, 2, 0, "P3"))
        self.progresses.append(PCB(3, 5, 0, "P4"))
        self.progresses.append(PCB(3, 1, 0, "P5"))
        self.progresses.append(PCB(2, 8, 0, "P6"))
        self.progresses.append(PCB(2, 6, 0, "P7"))
        self.progresses.append(PCB(2, 6, 0, "P8"))

    def print_all_progresses(self):
        print("当前队列中就绪的进程有:")
        print(str('name') + "\t" + str('priority') + "\t" + \
              str('come_time') + "\t" + str('execute_time') + "\t" + \
              str('status'))
        for i in range(len(self.progresses)):
            print(self.progresses[i])

    def execute_progress(self):
        while len(self.progresses) > 0:
            for i in range(len(self.progresses)):
                self.max_index = self.get_max_priority_index()
                self.progresses[self.max_index].hold_time -= 1
                if self.progresses[self.max_index].hold_time <= 0:
                    print("进程", self.progresses[self.max_index].progress_name, "执行完毕")

                    self.progresses.remove(self.progresses[self.max_index])

                self.print_all_progresses()
                time.sleep(1)
            self.__change_priority()
            print("===============================一次时间片轮回后结果:================================")
            self.print_all_progresses()
            time.sleep(1)

    def get_max_priority_index(self):
        max_index = 0
        for i in range(len(self.progresses)):
            if self.progresses[i].priority > self.progresses[max_index].priority:
                max_index = i
        self.progresses[max_index].priority = self.progresses[max_index].priority - 10
        return max_index

    def __change_priority(self):
        for i in range(len(self.progresses)):
            self.progresses[i].priority += 10


if __name__ == "__main__":
    priority = PriorityAlgorithm()
    print("初始化队列进程:===================================")
    priority.print_all_progresses()
    print("===================end============================")
    priority.execute_progress()

截图:
在这里插入图片描述

2、在采用页式存储管理的系统中,规定页长为1024字节,某进程页表的一部分如表

页号 块号
… …
24 121
21 63
70 16
34 81
请设计一个页地址转换程序,求出有效地址21996所对应的物理地址。

思路:
根据页面大小可计算出页内地址的位数
页内地址位数结合逻辑地址计算出页内地址(即,块内地址)和页号
页号结合页表,即可得出块号
块号&块内地址即可得出物理地址

代码:

class LogicAddress:
    address_dict = {24: 121, 21: 63, 70: 16, 34: 81}

    def __init__(self, address):
        self.a = bin(address)
        self.W = self.a[-10:]  # 页内地址
        self.P = int(self.a[self.a.index('b') + 1:-10], 2)  # 页号
        self.B = 0  # 块号
        self.physic_address = 0

    def to_physic(self):
        self.B = self.address_dict[self.P]
        self.physic_address = bin(self.B) + self.W
        return int(self.physic_address, 2)


if __name__ == '__main__':

    l = LogicAddress(21996)

    print(l.to_physic())

截图:
在这里插入图片描述

3、已知某进程用分段存储管理,段表如下。段号为3,段内位移量为149。请设计程序首先判断段是否越界,没有越界求出这两个逻辑地址对应的物理地址。

段号 段长 基址
0 1079 4631
1 321 1057
2 102 86
3 176 725
4 232 254

思路:
逻辑地址----- >段号、段内页号、业内地址
段表寄存器— >段表始址
段号+段表始址---- >页表始址
页表始址+段内页号----->存储块号
块号+页内地址------>物理地址

代码:

class SegmentTable:
    table = [[0, 1079, 4631], [1, 321, 1057], [2, 102, 86], [3, 176, 725], [4, 232, 254]]

    def __init__(self, id, address):
        self.id = id
        self.address = address
        for i in self.table:
            if i[0] == id:
                if i[1] <= address:
                    print("段越界")
                else:
                    self.address = i[2] + address

    def physic_address(self):
        return self.address


if __name__ == '__main__':
    s = SegmentTable(3, 149)

    print(s.physic_address())

截图:
在这里插入图片描述

4、在一个请求页式存储管理系统中,一个程序的页面走向依次为2,3,2,6,7,3,5,4,1。设分配给该程序的主存物理块为4块。请设计程序求出FIFO先来先服务算法在访问过程中页面置换及缺页情况。

思路:
最简单的页面置换算法是先入先出(FIFO)法。这种算法的实质是,总是选择在主存中停留时间最长(即最老)的一页置换,即先进入内存的页,先退出内存。理由是:最早调入内存的页,其不再被使用的可能性比刚调入内存的可能性大。建立一个FIFO队列,收容所有在内存中的页。被置换页面总是在队列头上进行。当一个页面被放入内存时,就把它插在队尾上。

代码:

class Queue:
    def __init__(self):
        self.list = []
        self.miss = 0

    def enqueue(self, item):
        print("页表添加", item)
        self.list.insert(0, item)

    def dequeue(self):
        item = self.list.pop()
        print(" 页表移除", item, end="")
        return item

    def number(self):
        return len(self.list)

    def is_in_queue(self, item):
        for i in self.list:
            if i == item:
                return True
        self.miss += 1
        print("发生缺页中断 ", end="")
        return False

    def read(self, item):
        print("访问", item)


if __name__ == '__main__':
    pages = [2, 3, 2, 6, 7, 3, 5, 4, 1]

    q = Queue()

    for i in pages:
        if q.is_in_queue(i):
            q.read(i)
        elif q.number() < 4:
            q.enqueue(i)
            q.read(i)
        else:
            q.dequeue()
            q.enqueue(i)
            q.read(i)
    print("缺页中断共发生", q.miss, "次")

截屏:
在这里插入图片描述

5、有一组磁道访问请求,需要访问的磁道号为:12、177、49、131、67,94,211、187、27,初始状态为磁头停留在67磁道处,请设计程序根据最短寻道时间优先(SSTF),列出磁道的访问序列。

思路:
SSTF:最短寻道时间算法,算法本质是贪心,已知磁头的初始位置,则最先被处理就是距离磁头位置最近的进程,处理完成后再处理距离当前磁道最近的进程,直到所有的进程被处理。

代码:

class SSTF:

    def __init__(self, init):
        self.address = init

    def read(self, item):
        print("访问: ", item)
        self.address = item


if __name__ == '__main__':
    s = SSTF(67)

    read_list = [12, 177, 49, 131, 67, 94, 211, 187, 27]

    while read_list:
        temp = 1000
        for i in range(len(read_list)):
            if abs(read_list[i] - s.address) < temp:
                temp = read_list[i]
        s.read(temp)
        read_list.remove(temp)

截图:

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值