SimPy 是一个基于标准 Python 的进程式离散事件仿真框架。可以用它建模实体(如顾客、车辆、数据包等)随时间相互交互、并竞争共享资源(如服务器、机器、带宽等)的系统。
【核心能力】
- 使用 Python 生成器函数进行进程建模;
- 共享资源管理(服务器、容器、仓库);
- 事件驱动的调度与同步;
- 与真实时钟同步的实时仿真;
- 监控与数据采集。
【适用场景】 适合以下情况使用:
- 建模离散事件系统——事件在非规则时间间隔发生的系统;
- 资源竞争——实体竞争有限资源(服务器、机器、人员);
- 排队分析——研究等待队列、服务时间和吞吐量;
- 流程优化——分析制造、物流或服务流程;
- 网络仿真——数据包路由、带宽分配、延迟分析;
- 容量规划——确定达到目标性能所需的最优资源水平;
- 系统验证——在实施前测试系统行为。
不适合:固定时间步的连续仿真(可考虑 SciPy ODE 求解器)、无资源共享的独立进程、纯数学优化(可考虑 SciPy optimize)。
【快速开始】 基本仿真结构:
import simpy
def process(env, name): """A simple process that waits and prints.""" print(f'{name} starting at {env.now}') yield env.timeout(5) print(f'{name} finishing at {env.now}')
env = simpy.Environment() env.process(process(env, 'Process 1')) env.process(process(env, 'Process 2')) env.run(until=10)
资源使用模式:
import simpy
def customer(env, name, resource): """Customer requests resource, uses it, then releases.""" with resource.request() as req: yield req # Wait for resource print(f'{name} got resource at {env.now}') yield env.timeout(3) # Use resource print(f'{name} released resource at {env.now}')
env = simpy.Environment() server = simpy.Resource(env, capacity=1)
env.process(customer(env, 'Customer 1', server)) env.process(customer(env, 'Customer 2', server)) env.run()
【核心概念】
- 环境(Environment):仿真环境管理时间并调度事件。
import simpy
env = simpy.Environment(initial_time=0)
import simpy.rt env_rt = simpy.rt.RealtimeEnvironment(factor=1.0)
env.run(until=100) # Run until time 100 env.run() # Run until no events remain
- 进程(Processes):进程使用 Python 生成器函数(带 yield 语句的函数)定义。
def my_process(env, param1, param2): print(f'Starting at {env.now}') yield env.timeout(5) print(f'Resumed at {env.now}') yield env.timeout(3) print(f'Done at {env.now}') return 'result'
env.process(my_process(env, 'value1', 'value2'))
- 事件(Events):事件是进程同步的基本机制。进程 yield 事件,并在事件被触发时恢复执行。常见事件类型包括:env.timeout(delay)、resource.request()、env.event()、env.process(func())、event1 & event2(等待全部事件 AllOf)、event1 | event2(等待任一事件 AnyOf)。
【资源类型】
- Resource:有限容量(服务器、机器)
- PriorityResource:基于优先级的排队
- PreemptiveResource:高优先级可中断低优先级
- Container:散装物料(燃料、水)
- Store:Python 对象存储(FIFO)
- FilterStore:选择性取项
- PriorityStore:按优先级排序的项
import simpy
env = simpy.Environment() resource = simpy.Resource(env, capacity=2) priority_resource = simpy.PriorityResource(env, capacity=1) fuel_tank = simpy.Container(env, capacity=100, init=50) warehouse = simpy.Store(env, capacity=10)
【常见仿真模式】 模式 1:顾客-服务台队列(含随机到达与服务时间,代码略)。 模式 2:生产者-消费者(通过 Store 的 put/get 协作,代码略)。 模式 3:并行任务执行(用 & 等待多个进程全部完成,代码略)。
【工作流程】 步骤 1:定义系统——明确实体、资源、进程与要测量的指标(等待时间、利用率、吞吐量)。 步骤 2:实现进程函数——为每种进程类型创建生成器函数,包含到达、请求资源、服务、离开等逻辑。 步骤 3:设置监控——可用 scripts/resource_monitor.py 中的 ResourceMonitor 等工具采集数据。
from scripts.resource_monitor import ResourceMonitor
resource = simpy.Resource(env, capacity=2) monitor = ResourceMonitor(env, resource, "Server") monitor.report()
步骤 4:运行与分析——运行仿真后生成报告并导出数据。
env.run(until=simulation_time) monitor.report() stats.report() monitor.export_csv('results.csv')
【高级特性】
- 进程交互:通过事件、进程 yield 和中断进行协作;核心机制包括事件通知、等待其他进程完成、中断以强制恢复进程(用于抢占)。
- 实时仿真:与真实时钟同步,适合硬件在环或交互式应用。
import simpy.rt
env = simpy.rt.RealtimeEnvironment(factor=1.0) # 1:1 time mapping
- 综合监控:监控进程、资源和事件,包括状态变量跟踪、资源 monkey-patching、事件追踪和统计采集。
【脚本与模板】
- basic_simulation_template.py:构建队列仿真的完整模板,含可配置参数、统计采集、顾客生成、资源使用和报告生成。
from scripts.basic_simulation_template import SimulationConfig, run_simulation
config = SimulationConfig() config.num_resources = 2 config.sim_time = 100 stats = run_simulation(config) stats.report()
- resource_monitor.py:可复用的监控工具,含 ResourceMonitor、MultiResourceMonitor、ContainerMonitor、自动统计计算和 CSV 导出。
from scripts.resource_monitor import ResourceMonitor
monitor = ResourceMonitor(env, resource, "My Resource") monitor.report() monitor.export_csv('data.csv')
【参考文档】 references/resources.md(所有资源类型及示例)、references/events.md(事件系统与模式)、references/process-interaction.md(进程同步)、references/monitoring.md(数据采集技巧)、references/real-time.md(实时仿真设置)。
【最佳实践】 始终在进程函数中使用 yield;使用 with resource.request() as req: 自动清理;设置 random.seed() 保证可复现;在整个仿真过程中采集数据;用解析解验证简单案例;为进程逻辑和参数选择添加注释;分离进程逻辑、统计与配置。
【常见陷阱】 忘记 yield;重复触发事件(事件只能触发一次);资源泄漏(使用上下文管理器或确保释放);进程中使用阻塞操作;时间单位不一致;死锁(确保至少一个进程能推进)。
【示例用例】
- 制造业:机器调度、生产线、库存管理;
- 医疗:急诊室仿真、患者流、人员分配;
- 电信:网络流量、数据包路由、带宽分配;
- 交通:交通流、物流、车辆路径;
- 服务运营:呼叫中心、零售结账、预约排程;
- 计算机系统:CPU 调度、内存管理、I/O 操作。