You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 09:57:04