SimPy如何让消息经过指定传输时长后再被Store的get方法获取
问题背景
需要使用SimPy模拟动态传输时延的通信流程:信源持续生成消息发往信宿,每条消息的传输时延独立,要求消息按生成时间+自身传输时长的时间点被接收,后生成但传输时长短的消息可以先到达信宿。
原实现问题
原代码的receieveMessage方法会在主循环中等待当前消息的传输时延完成,才会进入下一轮迭代取下一条消息,导致主接收进程被长时延消息阻塞,后续短时延消息的处理被挂起,无法实现乱序到达的效果。
解决方案
核心思路:主接收进程仅负责从链路队列中提取消息,每条消息的传输时延单独启动独立的SimPy子进程处理,主进程不等待时延完成,直接进入下一轮迭代,从根源上避免阻塞。
修改后完整代码
import simpy import random class Network: def __init__(self) -> None: self.env = simpy.Environment() self.cable = simpy.Store(self.env) def generate_message(self): i = 0 while True: # 修正原代码传输时延赋值不一致的问题 travel_time = 0.1 + round(random.random(), 3) message = (f'message: {i}', f'travel time {travel_time}', travel_time) print(f'gen at: {self.env.now} {message}') yield self.env.timeout(0.1) self.cable.put(message) def _process_single_message(self, message): # 独立子进程处理单条消息的传输时延 yield self.env.timeout(message[2]) print(f'receive at {self.env.now}, message: {message[:2]}') def receive_message(self): while True: message = yield self.cable.get() # 启动子进程处理时延,不阻塞主接收循环 self.env.process(self._process_single_message(message)) def run(self): self.env.process(self.generate_message()) self.env.process(self.receive_message()) self.env.run(until=1) if __name__ == "__main__": q = Network() q.run()
关键修改说明
- 新增
_process_single_message私有方法,封装单条消息的时延等待、接收打印逻辑 - 主接收循环中拿到消息后直接启动子进程,不添加
yield等待逻辑,主循环会立刻进入下一次迭代提取下一条消息 - 修正了原代码中传输时延赋值不一致的问题:原代码消息描述字段标注的是0.1+随机值,但实际时延字段用的是纯随机值,修改后两者保持一致
运行上述代码即可得到预期效果,消息会严格按照「生成时间+传输时长」的时间点被接收,不受长时延消息的阻塞影响。
内容的提问来源于stack exchange,提问作者Poramet Pathumsoot
相关产品推荐
相关产品推荐

