143 lines
4.2 KiB
Python
143 lines
4.2 KiB
Python
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 # 一次释放一个资源 |