具体做法是调度程序每次把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()
页号 块号
… …
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())
段号 段长 基址
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())
思路:
最简单的页面置换算法是先入先出(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, "次")
思路:
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)
截图: