
银行家算法在C#中的实现5进程3资源并发模拟与安全性检测1. 银行家算法核心原理银行家算法是一种经典的死锁避免算法由Edsger Dijkstra于1965年提出。其核心思想是通过模拟资源分配过程确保系统始终处于安全状态从而避免死锁发生。算法主要依赖以下数据结构Available长度为m的向量表示每类资源的可用数量Maxn×m矩阵记录每个进程对每类资源的最大需求Allocationn×m矩阵表示当前已分配给各进程的资源数量Needn×m矩阵计算每个进程还需要的资源数量Need Max - Allocation算法执行流程分为两个关键阶段资源请求检查验证请求是否超过进程声明的最大需求Need检查系统当前是否有足够资源满足请求Available安全性检查模拟分配后的系统状态寻找一个安全序列使得所有进程都能顺利完成// 银行家算法核心数据结构示例 public class BankerAlgorithm { private int[] Available; // 可用资源向量 private int[,] Max; // 最大需求矩阵 private int[,] Allocation;// 分配矩阵 private int[,] Need; // 需求矩阵 private int ProcessCount; // 进程数量 private int ResourceTypes;// 资源类型数量 // 计算Need矩阵 private void CalculateNeed() { for(int i0; iProcessCount; i) for(int j0; jResourceTypes; j) Need[i,j] Max[i,j] - Allocation[i,j]; } }2. C#实现架构设计2.1 类结构设计采用面向对象方式设计主要包含以下核心类BankerAlgorithm算法主类Process进程资源信息封装ResourceRequest资源请求封装SafetyChecker安全性检查器// 进程资源信息类 public class Process { public int Id { get; } public int[] MaxResources { get; } public int[] Allocated { get; private set; } public int[] Needed MaxResources.Zip(Allocated, (m,a) m-a).ToArray(); public Process(int id, int[] max) { Id id; MaxResources max; Allocated new int[max.Length]; } public void Allocate(int[] request) { for(int i0; irequest.Length; i) Allocated[i] request[i]; } }2.2 核心算法实现安全性检查算法的关键实现public bool IsSafeState() { int[] work (int[])Available.Clone(); bool[] finish new bool[ProcessCount]; // 寻找可满足的进程 while(true) { bool found false; for(int i0; iProcessCount; i) { if(!finish[i] NeedLessThanWork(i, work)) { // 模拟进程完成释放资源 for(int j0; jResourceTypes; j) work[j] Allocation[i,j]; finish[i] true; found true; break; } } if(!found) break; } return finish.All(f f); } private bool NeedLessThanWork(int pid, int[] work) { for(int i0; iResourceTypes; i) if(Need[pid,i] work[i]) return false; return true; }3. 并发模拟实现3.1 多进程资源请求处理模拟5个进程并发请求3类资源的场景public class ResourceSimulator { private BankerAlgorithm banker; private QueueResourceRequest pendingRequests new QueueResourceRequest(); public void ProcessRequest(int pid, int[] request) { if(!banker.ValidateRequest(pid, request)) { Console.WriteLine($非法请求进程{pid}请求资源超过其最大需求); return; } if(!banker.CheckResourceAvailable(request)) { pendingRequests.Enqueue(new ResourceRequest(pid, request)); Console.WriteLine($资源不足请求进入等待队列进程{pid}); return; } if(!banker.TryAllocate(pid, request)) { pendingRequests.Enqueue(new ResourceRequest(pid, request)); Console.WriteLine($分配可能导致不安全状态请求进入等待队列进程{pid}); } else { Console.WriteLine($成功为进程{pid}分配资源); CheckPendingRequests(); } } private void CheckPendingRequests() { while(pendingRequests.Count 0) { var req pendingRequests.Peek(); if(banker.TryAllocate(req.Pid, req.Request)) { pendingRequests.Dequeue(); Console.WriteLine($从等待队列中为进程{req.Pid}分配资源); } else { break; } } } }3.2 资源分配状态可视化实现资源分配状态的可视化输出public void PrintSystemStatus() { Console.WriteLine(\n当前系统资源分配状态); Console.WriteLine(进程\t最大需求\t已分配\t还需); for(int i0; iProcessCount; i) { Console.Write($P{i}\t); PrintResourceArray(GetRow(Max,i)); Console.Write(\t); PrintResourceArray(GetRow(Allocation,i)); Console.Write(\t); PrintResourceArray(GetRow(Need,i)); Console.WriteLine(); } Console.Write(可用资源); PrintResourceArray(Available); Console.WriteLine(\n); } private void PrintResourceArray(int[] arr) { Console.Write([); for(int i0; iarr.Length; i) { Console.Write(arr[i]); if(i arr.Length-1) Console.Write(, ); } Console.Write(]); }4. 测试用例设计4.1 安全状态测试初始资源可用资源[10, 5, 7]5个进程的最大需求矩阵进程A类B类C类P0753P1322P2902P3222P4433测试步骤P0请求[0,1,0]P1请求[2,0,0]P2请求[3,0,2]P3请求[2,1,1]P4请求[0,0,2]4.2 不安全状态测试在安全状态测试基础上 6. P0请求[1,0,1] → 应进入等待队列 7. P1请求[2,0,2] → 可分配 8. P1释放所有资源 → 触发等待队列处理4.3 边界条件测试测试资源刚好满足临界条件的情况初始可用资源[3,3,2]P0请求[3,3,2] → 系统进入临界状态任何额外请求都应进入等待5. 安全性检测流程优化5.1 检测算法优化传统安全性检测算法时间复杂度为O(n²×m)可通过以下方式优化public bool OptimizedSafetyCheck() { int[] work (int[])Available.Clone(); bool[] finish new bool[ProcessCount]; int count 0; // 按进程所需资源总量排序优先检查需求小的进程 var orderedProcesses Enumerable.Range(0, ProcessCount) .OrderBy(i GetTotalNeed(i)) .ToList(); foreach(int i in orderedProcesses) { if(!finish[i] NeedLessThanWork(i, work)) { for(int j0; jResourceTypes; j) work[j] Allocation[i,j]; finish[i] true; count; i -1; // 重新从头检查 } } return count ProcessCount; } private int GetTotalNeed(int pid) { int sum 0; for(int i0; iResourceTypes; i) sum Need[pid,i]; return sum; }5.2 并发请求处理策略采用多线程模拟真实并发环境public void SimulateConcurrentRequests() { var requests new List(int pid, int[] request) { (0, new[]{1,0,0}), (1, new[]{4,1,1}), (2, new[]{2,1,1}), (3, new[]{0,0,2}), (0, new[]{1,0,1}), (1, new[]{2,0,2}) }; Parallel.ForEach(requests, req { lock(this) { Console.WriteLine($进程{req.pid}发起资源请求...); ProcessRequest(req.pid, req.request); PrintSystemStatus(); } }); }6. 实际应用中的注意事项资源释放处理public void ReleaseResources(int pid, int[] release) { // 验证释放量不超过已分配量 for(int i0; iResourceTypes; i) { if(release[i] Allocation[pid,i]) throw new ArgumentException(释放量超过已分配量); } // 释放资源 for(int i0; iResourceTypes; i) { Allocation[pid,i] - release[i]; Available[i] release[i]; Need[pid,i] release[i]; } Console.WriteLine($进程{pid}释放资源成功); CheckPendingRequests(); }死锁预防策略设置请求超时机制实现资源预分配检查提供手动干预接口性能考量对于大规模系统可采用分区检查策略实现增量式安全性检查考虑引入资源分配优先级7. 扩展功能实现7.1 动态资源管理支持运行时动态添加/移除资源public void AddResource(int resourceType, int count) { if(resourceType 0 || resourceType ResourceTypes) throw new ArgumentException(无效资源类型); Available[resourceType] count; Console.WriteLine($已添加{count}个{resourceType}类资源); CheckPendingRequests(); } public void RemoveResource(int resourceType, int count) { if(Available[resourceType] count) throw new ArgumentException(移除量超过可用量); Available[resourceType] - count; Console.WriteLine($已移除{count}个{resourceType}类资源); }7.2 资源分配历史记录public class AllocationHistory { private ListAllocationRecord records new ListAllocationRecord(); public void AddRecord(int pid, int[] request, bool success) { records.Add(new AllocationRecord( DateTime.Now, pid, request, success )); } public void PrintHistory() { Console.WriteLine(\n资源分配历史记录); Console.WriteLine(时间\t\t进程\t请求\t结果); foreach(var r in records) { Console.Write(${r.Timestamp:HH:mm:ss}\tP{r.Pid}\t); PrintResourceArray(r.Request); Console.WriteLine($\t{(r.Success?成功:等待)}); } } }8. 完整示例代码结构项目目录结构建议BankerAlgorithm/ ├── Models/ │ ├── Process.cs │ ├── ResourceRequest.cs │ └── AllocationHistory.cs ├── Core/ │ ├── BankerAlgorithm.cs │ └── SafetyChecker.cs ├── Services/ │ └── ResourceSimulator.cs └── Program.cs核心调用示例// 初始化银行家算法 var banker new BankerAlgorithm( available: new[] {10, 5, 7}, max: new[,] { {7,5,3}, {3,2,2}, {9,0,2}, {2,2,2}, {4,3,3} } ); // 创建模拟器 var simulator new ResourceSimulator(banker); // 执行测试用例 simulator.ProcessRequest(0, new[] {0,1,0}); simulator.ProcessRequest(1, new[] {2,0,0}); simulator.ProcessRequest(2, new[] {3,0,2}); simulator.ProcessRequest(3, new[] {2,1,1}); simulator.ProcessRequest(4, new[] {0,0,2}); simulator.ProcessRequest(0, new[] {1,0,1}); // 应进入等待 simulator.ProcessRequest(1, new[] {2,0,2}); // 可分配 simulator.ReleaseResources(1, new[] {4,1,3}); // 释放P1资源