commit 92226ec4b130da8157b36602255d1c28e9a5639e Author: lotus Date: Thu Dec 5 19:45:11 2024 +0800 first commit diff --git a/command_interpreter.py b/command_interpreter.py new file mode 100644 index 0000000..c6d2b7a --- /dev/null +++ b/command_interpreter.py @@ -0,0 +1,251 @@ +import re +from typing import Dict, Any, Callable +from process_management import Process, ProcessState +from resource_management import ResourceType +from memory_management import MemoryAllocationStrategy + + +class CommandInterpreter: + """ + 解释并执行模拟操作系统的命令 + """ + + def __init__(self): + # 命令映射 + self.commands: Dict[str, Callable] = { + 'ALLOCATE': self.allocate_memory, + 'REQUEST_RESOURCE': self.request_resource, + 'RELEASE_RESOURCE': self.release_resource, + 'CREATE_FILE': self.create_file, + 'DELETE_FILE': self.delete_file, + 'READ_FILE': self.read_file, + 'WRITE_FILE': self.write_file, + 'DISK_SEEK': self.optimize_disk_seek, + } + + def execute_command(self, command: str, process: Process, os_system: Any): + """ + 解析并执行给定进程的命令 + + :param command: 要执行的命令字符串 + :param process: 执行命令的进程 + :param os_system: 操作系统引用 + """ + # 将命令分词 + tokens = command.strip().split() + + if not tokens: + return + + # 提取命令和参数 + cmd = tokens[0].upper() + args = tokens[1:] + + # 查找并执行相应的命令 + if cmd in self.commands: + try: + self.commands[cmd](process, os_system, *args) + except Exception as e: + print(f"执行命令 {cmd} 时出错: {e}") + else: + print(f"未知命令: {cmd}") + + def allocate_memory(self, process: Process, os_system: Any, size: str = None, strategy: str = None): + """ + 为进程分配内存 + + :param process: 请求内存分配的进程 + :param os_system: 操作系统引用 + :param size: 要分配的内存大小 + :param strategy: 内存分配策略 + """ + # 将大小转换为整数 + try: + memory_size = int(size or 1024) # 如果未指定,默认1KB + except ValueError: + memory_size = 1024 + + # 确定分配策略 + if strategy: + strategy = strategy.lower() + allocation_strategies = { + 'first': MemoryAllocationStrategy.FIRST_FIT, + 'best': MemoryAllocationStrategy.BEST_FIT, + 'worst': MemoryAllocationStrategy.WORST_FIT + } + os_system.memory_manager.allocation_strategy = allocation_strategies.get( + strategy, + MemoryAllocationStrategy.FIRST_FIT + ) + + # 分配内存 + start_address = os_system.memory_manager.allocate_memory( + process.pid, + memory_size + ) + + if start_address is not None: + print(f"进程 {process.pid} 分配了 {memory_size} 字节,地址为 {start_address}") + else: + print(f"进程 {process.pid} 内存分配失败") + + def request_resource(self, process: Process, os_system: Any, resource_type: str): + """ + 请求系统资源 + + :param process: 请求资源的进程 + :param os_system: 操作系统引用 + :param resource_type: 要请求的资源类型 + """ + # 将字符串映射到ResourceType + resource_types = { + 'PRINTER': ResourceType.PRINTER, + 'DISK': ResourceType.DISK, + 'NETWORK': ResourceType.NETWORK + } + + # 验证并请求资源 + try: + res_type = resource_types[resource_type.upper()] + success = os_system.resource_manager.request_resource(process.pid, res_type) + + if success: + print(f"进程 {process.pid} 成功分配了 {resource_type}") + else: + print(f"进程 {process.pid} 资源 {resource_type} 分配失败") + except KeyError: + print(f"无效的资源类型: {resource_type}") + + def release_resource(self, process: Process, os_system: Any, resource_type: str): + """ + 释放先前分配的资源 + + :param process: 释放资源的进程 + :param os_system: 操作系统引用 + :param resource_type: 要释放的资源类型 + """ + # 将字符串映射到ResourceType + resource_types = { + 'PRINTER': ResourceType.PRINTER, + 'DISK': ResourceType.DISK, + 'NETWORK': ResourceType.NETWORK + } + + try: + res_type = resource_types[resource_type.upper()] + + # 查找并释放分配给该进程的此类资源 + allocations = os_system.resource_manager.resource_allocations.get(process.pid, set()) + resources_to_release = [ + res for res in allocations + if res.type == res_type + ] + + for resource in resources_to_release: + os_system.resource_manager.release_resource(process.pid, resource) + print(f"进程 {process.pid} 释放了 {resource_type} 资源") + except KeyError: + print(f"无效的资源类型: {resource_type}") + + def create_file(self, process: Process, os_system: Any, filename: str): + """ + 在文件系统中创建文件 + + :param process: 创建文件的进程 + :param os_system: 操作系统引用 + :param filename: 要创建的文件名 + """ + try: + success = os_system.file_system.create_file(filename, process.pid) + if success: + print(f"进程 {process.pid} 创建了文件: {filename}") + else: + print(f"文件 {filename} 创建失败") + except Exception as e: + print(f"创建文件 {filename} 时出错: {e}") + + def delete_file(self, process: Process, os_system: Any, filename: str): + """ + 从文件系统中删除文件 + + :param process: 删除文件的进程 + :param os_system: 操作系统引用 + :param filename: 要删除的文件名 + """ + try: + success = os_system.file_system.delete_file(filename, process.pid) + if success: + print(f"进程 {process.pid} 删除了文件: {filename}") + else: + print(f"文件 {filename} 删除失败") + except Exception as e: + print(f"删除文件 {filename} 时出错: {e}") + + def read_file(self, process: Process, os_system: Any, filename: str, offset: str = '0', size: str = None): + """ + 从文件系统中读取文件 + + :param process: 读取文件的进程 + :param os_system: 操作系统引用 + :param filename: 要读取的文件名 + :param offset: 文件起始字节偏移量 + :param size: 要读取的字节数 + """ + try: + # 将偏移量和大小转换为整数 + offset_bytes = int(offset) + read_size = int(size) if size else None + + content = os_system.file_system.read_file( + filename, + process.pid, + offset_bytes, + read_size + ) + + print(f"进程 {process.pid} 从文件 {filename} 读取: {content}") + except Exception as e: + print(f"读取文件 {filename} 时出错: {e}") + + def write_file(self, process: Process, os_system: Any, filename: str, offset: str = '0', content: str = ''): + """ + 向文件系统中的文件写入内容 + + :param process: 写入文件的进程 + :param os_system: 操作系统引用 + :param filename: 要写入的文件名 + :param offset: 文件起始字节偏移量 + :param content: 要写入的内容 + """ + try: + # 将偏移量转换为整数 + offset_bytes = int(offset) + + success = os_system.file_system.write_file( + filename, + process.pid, + offset_bytes, + content + ) + + if success: + print(f"进程 {process.pid} 写入了文件 {filename}") + else: + print(f"文件 {filename} 写入失败") + except Exception as e: + print(f"写入文件 {filename} 时出错: {e}") + + def optimize_disk_seek(self, process: Process, os_system: Any, *seek_params): + """ + 优化磁盘寻道操作 + + :param process: 请求磁盘寻道优化的进程 + :param os_system: 操作系统引用 + :param seek_params: 磁盘寻道优化的参数 + """ + try: + # 调用磁盘管理器的寻道优化方法 + os_system.disk_manager.optimize_seek_operations() + print(f"进程 {process.pid} 请求了磁盘寻道优化") + except Exception as e: + print(f"磁盘寻道优化失败: {e}") \ No newline at end of file diff --git a/memory_management.py b/memory_management.py new file mode 100644 index 0000000..47b2357 --- /dev/null +++ b/memory_management.py @@ -0,0 +1,138 @@ +from dataclasses import dataclass, field +from typing import List, Dict, Optional, Tuple +import math + + +class MemoryAllocationStrategy: + """ + 内存分配策略 + """ + FIRST_FIT = 'first_fit' # 首次适应算法 + BEST_FIT = 'best_fit' # 最佳适应算法 + WORST_FIT = 'worst_fit' # 最坏适应算法 + + +@dataclass +class MemoryBlock: + """ + 表示内存块 + """ + start_address: int # 起始地址 + size: int # 内存块大小 + is_free: bool = True # 是否空闲 + process_id: Optional[int] = None # 占用该内存块的进程ID + + +class MemoryManager: + """ + 管理内存分配、释放和虚拟内存 + """ + + def __init__( + self, + total_memory: int = 1024 * 1024, # 默认1MB + page_size: int = 4096, # 4KB页大小 + allocation_strategy: str = MemoryAllocationStrategy.FIRST_FIT + ): + self.total_memory = total_memory # 总内存大小 + self.page_size = page_size # 页大小 + self.allocation_strategy = allocation_strategy # 分配策略 + + # 内存块映射 + self.memory_map: List[MemoryBlock] = [ + MemoryBlock(0, total_memory) + ] + + # 虚拟内存的页表 + self.page_table: Dict[int, List[Tuple[int, bool]]] = {} + + # 缺页跟踪 + self.total_memory_accesses = 0 + self.page_faults = 0 + + def allocate_memory( + self, + process_id: int, + memory_size: int + ) -> Optional[int]: + """ + 为进程分配内存 + + :param process_id: 请求内存的进程ID + :param memory_size: 要分配的内存大小 + :return: 分配的内存起始地址,分配失败返回None + """ + # 根据分配策略选择内存分配方法 + allocation_method = { + MemoryAllocationStrategy.FIRST_FIT: self._first_fit_allocation, + MemoryAllocationStrategy.BEST_FIT: self._best_fit_allocation, + MemoryAllocationStrategy.WORST_FIT: self._worst_fit_allocation + }.get(self.allocation_strategy) + + return allocation_method(process_id, memory_size) + + def _first_fit_allocation( + self, + process_id: int, + memory_size: int + ) -> Optional[int]: + """ + 首次适应内存分配策略 + + :param process_id: 请求内存的进程ID + :param memory_size: 要分配的内存大小 + :return: 分配的内存起始地址,分配失败返回None + """ + for i, block in enumerate(self.memory_map): + if block.is_free and block.size >= memory_size: + # 如果内存块大于请求大小,则分割块 + if block.size > memory_size: + new_block = MemoryBlock( + block.start_address + memory_size, + block.size - memory_size + ) + self.memory_map.insert(i + 1, new_block) + + # 更新原内存块 + block.is_free = False + block.process_id = process_id + block.size = memory_size + + return block.start_address + + return None + + def _best_fit_allocation( + self, + process_id: int, + memory_size: int + ) -> Optional[int]: + """ + 最佳适应内存分配策略 + + :param process_id: 请求内存的进程ID + :param memory_size: 要分配的内存大小 + :return: 分配的内存起始地址,分配失败返回None + """ + best_block = None + best_block_index = -1 + smallest_difference = float('inf') + + for i, block in enumerate(self.memory_map): + if block.is_free and block.size >= memory_size: + difference = block.size - memory_size + if difference < smallest_difference: + smallest_difference = difference + best_block = block + best_block_index = i + + if best_block: + # 如果内存块大于请求大小,则分割块 + if best_block.size > memory_size: + new_block = MemoryBlock( + best_block.start_address + memory_size, + best_block.size - memory_size + ) + self.memory_map.insert(best_block_index + 1, new_block) + + # 更 \ No newline at end of file diff --git a/process_management.py b/process_management.py new file mode 100644 index 0000000..39cca0e --- /dev/null +++ b/process_management.py @@ -0,0 +1,162 @@ +import enum +from dataclasses import dataclass, field +from typing import List, Dict, Optional +import time +import heapq + + +class ProcessState(enum.Enum): + """操作系统中的进程状态""" + NEW = 0 # 进程刚创建 + READY = 1 # 等待被分配到处理器的进程 + RUNNING = 2 # 当前正在执行的进程 + WAITING = 3 # 等待某些事件的进程(I/O、资源分配) + TERMINATED = 4 # 已完成执行的进程 + + +@dataclass +class Process: + """表示操作系统中的进程""" + pid: int + script_path: str + state: ProcessState = field(default=ProcessState.NEW) + priority: int = field(default=0) + arrival_time: float = field(default_factory=time.time) + start_time: Optional[float] = None + completion_time: Optional[float] = None + cpu_time: float = 0.0 + waiting_time: float = 0.0 + + +class ProcessManager: + """ + 管理进程调度和生命周期 + 实现多种调度算法 + """ + + def __init__(self): + self.processes: Dict[int, Process] = {} + self.ready_queue: List[Process] = [] + self.next_pid = 1 + self.total_processes = 0 + + def create_process(self, script_path: str, priority: int = 0) -> Process: + """ + 创建新进程 + + :param script_path: 进程脚本路径 + :param priority: 进程优先级(数字越小优先级越高) + :return: 创建的进程 + """ + process = Process( + pid=self.next_pid, + script_path=script_path, + priority=priority + ) + self.processes[self.next_pid] = process + self.next_pid += 1 + self.total_processes += 1 + + # 将进程移至就绪状态 + self._change_process_state(process, ProcessState.READY) + + return process + + def _change_process_state(self, process: Process, new_state: ProcessState): + """ + 改变进程状态并更新相关时间戳 + + :param process: 要更新的进程 + :param new_state: 进程的新状态 + """ + old_state = process.state + process.state = new_state + + # 跟踪性能指标的计时 + current_time = time.time() + if new_state == ProcessState.RUNNING: + process.start_time = current_time + elif new_state == ProcessState.TERMINATED: + process.completion_time = current_time + + def schedule_process(self) -> Optional[Process]: + """ + 选择并调度要运行的进程 + 使用基于优先级的抢占式调度 + + :return: 要运行的进程,如果没有就绪进程则返回None + """ + if not self.ready_queue: + return None + + # 按优先级对就绪队列排序(数字越小优先级越高) + self.ready_queue.sort(key=lambda p: p.priority) + + # 选择最高优先级进程 + selected_process = self.ready_queue[0] + self._change_process_state(selected_process, ProcessState.RUNNING) + + return selected_process + + def terminate_process(self, process: Process): + """ + 终止进程并更新其状态 + + :param process: 要终止的进程 + """ + self._change_process_state(process, ProcessState.TERMINATED) + + # 如果在就绪队列中,则移除 + if process in self.ready_queue: + self.ready_queue.remove(process) + + def get_total_processes(self) -> int: + """ + 获取已创建的进程总数 + + :return: 进程总数 + """ + return self.total_processes + + def calculate_avg_turnaround_time(self) -> float: + """ + 计算已完成进程的平均周转时间 + + :return: 平均周转时间 + """ + completed_processes = [ + p for p in self.processes.values() + if p.completion_time is not None + ] + + if not completed_processes: + return 0.0 + + turnaround_times = [ + p.completion_time - p.arrival_time + for p in completed_processes + ] + + return sum(turnaround_times) / len(turnaround_times) + + def calculate_avg_weighted_turnaround_time(self) -> float: + """ + 计算平均带权周转时间 + 带权周转时间 = (完成时间 - 到达时间) / CPU时间 + + :return: 平均带权周转时间 + """ + completed_processes = [ + p for p in self.processes.values() + if p.completion_time is not None and p.cpu_time > 0 + ] + + if not completed_processes: + return 0.0 + + weighted_turnaround_times = [ + (p.completion_time - p.arrival_time) / p.cpu_time + for p in completed_processes + ] + + return sum(weighted_turnaround_times) / len(weighted_turnaround_times) \ No newline at end of file diff --git a/resource_management.py b/resource_management.py new file mode 100644 index 0000000..58c1647 --- /dev/null +++ b/resource_management.py @@ -0,0 +1,143 @@ +from dataclasses import dataclass, field +from typing import List, Dict, Set +import threading +from enum import Enum, auto + + +class ResourceType(Enum): + """ + 表示不同类型的系统资源 + """ + PRINTER = auto() + DISK = auto() + MEMORY = auto() + NETWORK = auto() + + +@dataclass +class Resource: + """ + 表示系统资源 + """ + id: int + type: ResourceType + is_available: bool = True + current_owner: int = None # 当前使用该资源的进程ID + + +class DeadlockAvoidanceStrategy: + """ + 死锁预防和解决的策略 + """ + RESOURCE_ALLOCATION_GRAPH = 'resource_allocation_graph' + BANKER_ALGORITHM = 'banker_algorithm' + + +class ResourceManager: + """ + 管理系统资源分配和死锁预防 + """ + + def __init__(self): + # 资源池 + self.resources: Dict[ResourceType, List[Resource]] = { + ResourceType.PRINTER: [Resource(i, ResourceType.PRINTER) for i in range(3)], + ResourceType.DISK: [Resource(i, ResourceType.DISK) for i in range(2)], + ResourceType.NETWORK: [Resource(i, ResourceType.NETWORK) for i in range(1)], + } + + # 跟踪资源请求和分配 + self.resource_requests: Dict[int, Set[Resource]] = {} + self.resource_allocations: Dict[int, Set[Resource]] = {} + + # 死锁预防 + self.allocation_lock = threading.Lock() + self.deadlock_strategy = DeadlockAvoidanceStrategy.BANKER_ALGORITHM + + def request_resource( + self, + process_id: int, + resource_type: ResourceType + ) -> bool: + """ + 为进程请求资源 + + :param process_id: 请求资源的进程ID + :param resource_type: 要请求的资源类型 + :return: 如果资源分配成功,返回True,否则返回False + """ + with self.allocation_lock: + # 查找指定类型的可用资源 + available_resources = [ + res for res in self.resources[resource_type] + if res.is_available + ] + + if not available_resources: + # 没有可用资源 + return False + + # 分配第一个可用资源 + resource = available_resources[0] + resource.is_available = False + resource.current_owner = process_id + + # 跟踪资源分配 + if process_id not in self.resource_allocations: + self.resource_allocations[process_id] = set() + self.resource_allocations[process_id].add(resource) + + return True + + def release_resource( + self, + process_id: int, + resource: Resource + ): + """ + 释放先前分配给进程的资源 + + :param process_id: 释放资源的进程ID + :param resource: 要释放的资源 + """ + with self.allocation_lock: + # 验证进程是否拥有该资源 + if (resource.current_owner != process_id or + resource.type not in self.resources): + return + + # 标记资源为可用 + resource.is_available = True + resource.current_owner = None + + # 从分配中移除 + if process_id in self.resource_allocations: + self.resource_allocations[process_id].discard(resource) + + def detect_deadlock(self) -> bool: + """ + 使用资源分配图检测潜在的死锁 + + :return: 如果检测到死锁,返回True,否则返回False + """ + # 使用资源分配图进行简单的死锁检测 + for process, resources in self.resource_allocations.items(): + for resource in resources: + # 检查资源是否循环依赖 + if resource.current_owner != process: + return True + + return False + + def resolve_deadlock(self): + """ + 使用资源抢占解决死锁 + """ + if not self.detect_deadlock(): + return + + # 从进程中抢占资源 + for process, resources in list(self.resource_allocations.items()): + for resource in list(resources): + self.release_resource(process, resource) + break # 一次释放一个资源 \ No newline at end of file diff --git a/stimulate_operating_system.py b/stimulate_operating_system.py new file mode 100644 index 0000000..2f89c46 --- /dev/null +++ b/stimulate_operating_system.py @@ -0,0 +1,97 @@ +import sys +import time +from typing import List, Dict, Any +from dataclasses import dataclass, field + +# 导入其他模块 +from process_management import ProcessManager +from memory_management import MemoryManager +from resource_management import ResourceManager +# from file_system import FileSystem +# from disk_management import DiskManager +from command_interpreter import CommandInterpreter + + +@dataclass +class OperatingSystem: + """ + 模拟操作系统核心类 + """ + process_manager: ProcessManager = field(default_factory=ProcessManager) + memory_manager: MemoryManager = field(default_factory=MemoryManager) + resource_manager: ResourceManager = field(default_factory=ResourceManager) + # file_system: FileSystem = field(default_factory=FileSystem) + # disk_manager: DiskManager = field(default_factory=DiskManager) + command_interpreter: CommandInterpreter = field(default_factory=CommandInterpreter) + + def execute_job_script(self, script_path: str): + """ + 通过命令解释器执行作业脚本 + + :param script_path: 作业脚本文件路径 + """ + try: + # 读取并解析脚本 + with open(script_path, 'r') as script_file: + script_lines = script_file.readlines() + + # 为脚本创建作业/进程 + job = self.process_manager.create_process(script_path) + + # 解释并执行命令 + for line in script_lines: + line = line.strip() + if line: + self.command_interpreter.execute_command(line, job, self) + + # 完成进程 + self.process_manager.terminate_process(job) + + except Exception as e: + print(f"执行作业脚本 {script_path} 时出错: {e}") + + def run_system(self, job_scripts: List[str]): + """ + 并发运行多个作业脚本 + + :param job_scripts: 要执行的脚本路径列表 + """ + # 模拟并发作业处理 + for script in job_scripts: + try: + self.execute_job_script(script) + except Exception as e: + print(f"作业 {script} 出错: {e}") + + # 计算并显示系统性能指标 + self.display_system_performance() + + def display_system_performance(self): + """ + 显示整体系统性能指标 + """ + print("\n--- 系统性能指标 ---") + print(f"总进程数: {self.process_manager.get_total_processes()}") + print(f"平均周转时间: {self.process_manager.calculate_avg_turnaround_time():.2f}") + print(f"平均带权周转时间: {self.process_manager.calculate_avg_weighted_turnaround_time():.2f}") + print(f"缺页率: {self.memory_manager.calculate_page_fault_rate():.2%}") + # print(f"磁盘寻道优化: {self.disk_manager.get_seek_optimization_metric()}") + + +def main(): + # 创建操作系统实例 + os_sim = OperatingSystem() + + # 模拟作业脚本 + job_scripts = [ + 'job1_script.txt', + 'job2_script.txt', + 'job3_script.txt' + ] + + # 运行操作系统模拟 + os_sim.run_system(job_scripts) + + +if __name__ == '__main__': + main() \ No newline at end of file