【队列】用队列模拟打印机的等待时间

用于打印机任务的仿真:一段时间内,打印任务和打印机状态的模拟

构造三个对象:
(1)打印机:实现了打印机的打印速度、剩余打印时间、打印任务三个属性,以及是否闲置、开启一项新任务和打印三个方法
(2)打印任务:实现了任务的随机生成、任务量的生成、等待时间统计
(3)打印队列:实现了打印任务的入列和出列操作,从而完成了打印任务和打印机之间的交互

以时间(每秒)为单位,依次进行:1)是否生成新的打印任务;2)若生成新任务的话,入列;3)查看打印机状态;4)若打印机闲置,队列有任务的化出列进行打印;
5)打印机有任务打印;6)查看打印任务的完成情况,并视情重置打印机状态

import random

# 全局变量
PPM = 5         # page per minute, 打印机每分钟打印张数
TP = 21         # task page, 随机任务的张数上限
TF = 180        # task frequency, 平均每多少s随机生成一个任务



# 队列类
class Quene(object):
    def __init__(self):
        self.data = []

    def __repr__(self):
        return f"Quene({self.data})"

    def enquene(self, value):
        # 入队列
        self.data.append(value)

    def dequene(self):
        # 出队列
        if self.isEmpty():
            raise IndexError("dequene from empty quene")
        else:
            return self.data.pop(0)

    def __len__(self):
        return len(self.data)

    def isEmpty(self):
        return len(self.data) == 0

    def rotate(self,times):
        # 队列的顺序翻转
        for _ in range(times):
            self.enquene(self.dequene())

class Printer(object):
    def __init__(self, ppm):
        self.ppm = ppm    # 超参,每分钟打印速度
        self.remaining_time = 0        # 剩余打印时间初始值
        self.current_task = None    # 当前任务

    def tick(self):
        # 以s为单位,打印
        self.remaining_time -= 1
        if self.remaining_time < 0:
            self.current_task = None

    def isBusy(self):
        # 校验打印机是否在工作
        if self.current_task:
            return True
        else:
            return False

    def start_task(self, task):
        # 开启新的任务
        self.current_task = task
        self.remaining_time = task.get_pages() * 60 / self.ppm


class Task(object):
    def __init__(self, time_stamp):
        self.task_pages = random.randrange(1, TP)
        self.time_stamp = time_stamp    # 生成任务时生成时间戳,以统计等待时间

    def get_time(self):
        return self.time_stamp

    def get_pages(self):
        return self.task_pages

    def wait_time(self, current_time):   # 统计等待时间
        return current_time - self.time_stamp


def simulate(total_time):
    """
    仿真主程序
    """
    printer = Printer(PPM)
    printer_quene = Quene()

    wait_time_list = []       # 所有需等待任务的等待时间列表

    for t in range(total_time):
        # 1. 根据随机数是否生成新任务,并加入队列
        choice = random.randrange(1, TF + 1)
        if choice == TF:
            new_task = Task(t)
            printer_quene.enquene(new_task)

        # 2. 视情决定是否将任务进行打印
        if not printer.isBusy() and not printer_quene.isEmpty():
            dequene_task = printer_quene.dequene()
            printer.start_task(dequene_task)
            wait_time = dequene_task.wait_time(t)
            wait_time_list.append(wait_time)

        # 3. 视情进行打印
        if printer.current_task:
            printer.tick()

        # 4. 统计等待时间

    waiting_num = len(printer_quene)
    average_wait_time = sum(wait_time_list) / len(wait_time_list)
    print("{} tasks remain waiting, the average time of waiting is {}!".format(waiting_num, average_wait_time))


if __name__ == '__main__':
    for i in range(10):
        simulate(3600)


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
API之网络函数1. API之网络函数 WNetAddConnection 创建同一个网络资源的永久性连接 WNetAddConnection2 创建同一个网络资源的连接 WNetAddConnection3 创建同一个网络资源的连接 WNetCancelConnection 结束一个网络连接 WNetCancelConnection2 结束一个网络连接 WNetCloseEnum 结束一次枚举操作 WNetConnectionDialog 启动一个标准对话框,以便建立同网络资源的连接 WNetDisconnectDialog 启动一个标准对话框,以便断开同网络资源的连接 WNetEnumResource 枚举网络资源 WNetGetConnection 获取本地或已连接的一个资源的网络名称 WNetGetLastError 获取网络错误的扩展错误信息 WNetGetUniversalName 获取网络中一个文件的远程名称以及/或者UNC(统一命名规范)名称 WNetGetUser 获取一个网络资源用以连接的名字 WNetOpenEnum 启动对网络资源进行枚举的过程 2. API之消息函数 BroadcastSystemMessage 将一条系统消息广播给系统中所有的顶级窗口 GetMessagePos 取得消息队列中上一条消息处理完毕时的鼠标指针屏幕位置 GetMessageTime 取得消息队列中上一条消息处理完毕时的时间 PostMessage 将一条消息投递到指定窗口的消息队列 PostThreadMessage 将一条消息投递给应用程序 RegisterWindowMessage 获取分配给一个字串标识符的消息编号 ReplyMessage 答复一个消息 SendMessage 调用一个窗口的窗口函数,将一条消息发给那个窗口 SendMessageCallback 将一条消息发给窗口 SendMessageTimeout 向窗口发送一条消息 SendNotifyMessage 向窗口发送一条消息 3. API之文件处理函数 CloseHandle 关闭一个内核对象。其中包括文件、文件映射、进程、线程、安全和同步对象等 CompareFileTime 对比两个文件的时间 CopyFile 复制文件 CreateDirectory 创建一个新目录 CreateFile 打开和创建文件、管道、邮槽、通信服务、设备以及控制台 CreateFileMapping 创建一个新的文件映射对象 DeleteFile 删除指定文件 DeviceIoControl 对设备执行指定的操作 DosDateTimeToFileTime 将DOS日期和时间值转换成一个 win32 FILETIME 值 FileTimeToDosDateTime 将一个 win32 FILETIME 值转换成DOS日期和时间值 FileTimeToLocalFileTime 将一个FILETIME结构转换成本地时间 FileTimeToSystemTime 根据一个FILETIME结构的内容,装载一个SYSTEMTIME结构 FindClose 关闭由FindFirstFile函数创建的一个搜索句柄 FindFirstFile 根据文件名查找文件 FindNextFile 根据调用FindFirstFile函数时指定的一个文件名查找下一个文件 FlushFileBuffers 针对指定的文件句柄,刷新内部文件缓冲区 FlushViewOfFile 将写入文件映射缓冲区的所有数据都刷新到磁盘 GetBinaryType 判断文件是否可以执行 GetCompressedFileSize 判断一个压缩文件在磁盘上实际占据的字节数 GetCurrentDirectory 在一个缓冲区中装载当前目录 GetDiskFreeSpace 获取与一个磁盘的组织有关的信息,以及了解剩余空间的容量 GetDiskFreeSpaceEx 获取与一个磁盘的组织以及剩余空间容量有关的信息 GetDriveType 判断一个磁盘驱动器的类型 GetExpandedName 取得一个压缩文件的全名 GetFileAttributes 判断指定文件的属性 GetFileInformationByHandle 这个函数提供了获取文件信息的一种机制 GetFileSize 判断文件长度 GetFileTime 取得指定文件的时间信息 GetFileType 在给出文件句柄的前提下,判断文件类型 GetFileVersionInfo 从支持版本标记的一个模块里获取文件版本信息
1.实验目的 加深对作业调度算法的理解。 2.实验内容 此实验模拟批处理系统中的作业调度,并采用响应比高者优先算法作为作业调度算法。 3.实验说明 从输入井中选择作业读入内存,使其获得处理器,得到运行的机会,即为作业调度。输入井中的作业用“作业控制块”(JCB)标识,为了进行作业调度,将作业控制块组成一个队列,这个队列称为后备队列模拟实验中没有实际作业,作业控制块中的信息内容只使用了模拟实验中需要的数据。作业控制块中包括作业名、作业大小、所需打印机台数、所需磁带机数量、作业估计执行时间、作业等待时间、指向下一个作业控制块的指针等内容。将作业控制块组成一个队列,实验中采用动态链表的方式模拟作业的后备队列。作业控制块采用结构型数据模拟模拟实验中,主存采用可移动的可变分区管理方法,即只要主存空闲区总和比作业大就可以满足作业对主存的需求。对打印机和磁带机这两种独占设备采用静态分配法,即作业执行前必须获得所需资源,并且执行完才归还。 实验中作业的调度采用响应比高者优先算法。响应比为作业的等待时间和作业估计执行时间之比。首先计算出输入井中满足条件的作业的响应比,从中选择响应比最高的一个作业装入主存储器,分配资源。由于是模拟实验,可将作业控制块出队装入主存储器的工作用输出作业名模拟,同时修改系统的资源数量。 模拟实验时,可以首先假设系统的资源情况。假设系统资源只有主存64MB、磁带机4台、打印机2台,然后手工输入某个时刻输入井中的各个作业情况,最后进行作业调度,并将结果输出。 批处理系统中的作业调度模拟程序主要由创建作业队列的程序段(在主函数中)和作业调度函数组成。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值