Simpy 中的资源未释放 - 我做错了什么?

2024-03-06

我已按照建议简化了代表问题的代码并尝试进行调试。

这是代码的最简单版本,但仍然包含错误:

import simpy

SIM_TIME = 5

def source(env):    
    i = 0
    while True:
        i += 1
        env.process(train(env, 'Train %d' % i, 'a'))
        yield env.timeout(1)
        i += 1
        env.process(train(env, 'Train %d' % i, 'b'))
        yield env.timeout(1)

def train(env, name, route):
    resource_req = resource.request()
    p3_req = p3.request()

    if route == 'a':
        print 'Route a %s generated' % name
        yield resource_req
        print 'Route a %s seized resource at time %d' % (name, env.now)
        yield env.timeout(1)
        resource.release(resource_req) 
        print 'Route a %s released resource at time %d' % (name, env.now)

    elif route == 'b':
        print 'Route b %s generated' % name
        yield p3_req
        print 'Route b %s seized resource at time %d' % (name, env.now)
        yield env.timeout(1)
        p3.release(p3_req)
        print 'Route b %s released resource at time %d' % (name, env.now)

    else:
        print 'Could not find a route branch'

env = simpy.Environment()

resource = simpy.Resource(env, 1)
p3 = simpy.Resource(env, 1)

env.process(source(env))
env.run(until=SIM_TIME)

运行此命令的输出:

Route a Train 1 generated
Route a Train 1 seized resource at time 0
Route b Train 2 generated
Route a Train 1 released resource at time 1
Route a Train 3 generated
Route b Train 4 generated
Route a Train 5 generated

正如您所看到的,资源显然在“路线 a”上被释放,但随后在路线 a 或路线 b 上都无法占用其他资源。

我对此很困惑。任何帮助将非常感激!


我相信问题的出现是因为发布引用了一个特定的请求,但该请求此时已经被新的请求覆盖了。 resource_req 是请求,但在释放之前,它会被新的resource_req 覆盖。我相信,当您尝试释放这个新请求时,它不会正确释放它,因为它不是由资源处理的释放(它是新的)。

我不知道解决方案是什么。我偶然发现这篇文章试图找到它,因为我自己也遇到了同样的问题。一个明显的可能性(我还没有尝试过)是创建一个请求列表,并跟踪它们,但这似乎是一个愚蠢的解决方案。必须有一种方法可以简单地释放资源(这是所需的行为)。如果我弄清楚了,我会尝试回复!

这是一个最小的工作示例:

import simpy

class Machine:
    def __init__(self,env):
        self.machine = simpy.Resource(env,capacity=1)
        self.load_proc = env.process(self.load(env))

    def load(self,env):
        "Load machine 1 when it's empty"
        while True:
            self.req = self.machine.request()
            print("Waiting for machine at %d" %env.now)
            yield self.req
            print("Load machine at %d" %env.now)
            self.process_proc = env.process(self.process(env))

    def process(self,env):
        "Machine does process and is then emptied"
        print("Machine starts process at %d" %env.now)
        yield env.timeout(10)
        print("Machine finished process at %d" %env.now)
        self.machine.release(self.req)
        print("Machine released at %d" %env.now)

env = simpy.Environment()
M1 = Machine(env)
env.run(until=100)

这里有一台机器不断尝试加载,但等待其空载。加载后,它会尝试运行 10 秒的进程,然后释放资源以允许再次加载。在 100 个时间步长中,它显然应该能够生成 10 个批次,但只完成了第一个批次。

>>> 
Waiting for machine at 0
Load machine at 0
Waiting for machine at 0
Machine starts process at 0
Machine finished process at 10
Machine released at 10
>>> 

看来发布不起作用,因为它指的是第二个请求。诊断此问题可以找到解决方法,但最好知道正确的方法!


一种可能的解决方案是仅释放当前用户而不是特定请求:

import simpy

class Machine:
    def __init__(self,env):
        self.machine = simpy.Resource(env,capacity=1)
        self.load_proc = env.process(self.load(env))

    def load(self,env):
        "Load machine 1 when it's empty"
        while True:
            print("Waiting for machine at %d" %env.now)
            yield self.machine.request()
            print("Load machine at %d" %env.now)
            self.process_proc = env.process(self.process(env))

    def process(self,env):
        "Machine does process and is then emptied"
        print("Machine starts process at %d" %env.now)
        yield env.timeout(10)
        print("Machine finished process at %d" %env.now)
        if len(self.machine.users)>=1: self.machine.release(self.machine.users[0])
        print("Machine released at %d" %env.now)

env = simpy.Environment()
M1 = Machine(env)
env.run(until=100)

其行为符合预期,并且优点是您不需要为请求提供变量。的释放

self.machine.release(self.machine.users[0])

可能就足够了,除非您面临发布尚未请求的内容的风险。


更新基于斯特凡·舍夫克的 https://stackoverflow.com/users/3564517/stefan-scherfke注释,是将 req 显式传递给新进程:

import simpy

class Machine:
    def __init__(self,env):
        self.machine = simpy.Resource(env,capacity=1)
        self.load_proc = env.process(self.load(env))

    def load(self,env):
        "Load machine 1 when it's empty"
        while True:
            print("Waiting for machine at %d" %env.now)
            req = self.machine.request()
            yield req
            print("Load machine at %d" %env.now)
            self.process_proc = env.process(self.process(env,req))

    def process(self,env,req):
        "Machine does process and is then emptied"
        print("Machine starts process at %d" %env.now)
        yield env.timeout(10)
        print("Machine finished process at %d" %env.now)
        self.machine.release(req)
        print("Machine released at %d" %env.now)

env = simpy.Environment()
M1 = Machine(env)
env.run(until=100)

这确实按预期工作。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Simpy 中的资源未释放 - 我做错了什么? 的相关文章

  • 适用于 Python 3.x 的 Hive 客户端

    是否可以使用 Python 3 x 连接到 hadoop 并运行 hive 查询 我正在使用Python 3 4 1 我发现可以按照这里写的方式完成 https cwiki apache org confluence display Hiv
  • 以 str.format 切片字符串

    我想实现以下目标str format x y 1234 5678 print str x 2 str y 2 我能够做到这一点的唯一方法是 print 0 1 format str x 2 str y 2 现在 这是一个例子 我真正拥有的是
  • Pytorch - 推断线性层 in_features

    我正在构建一个玩具模型来获取一些图像并进行分类 我的模型看起来像 conv2d gt pool gt conv2d gt linear gt linear 我的问题是 当我们创建模型时 我们必须计算第一个线性层的大小in features基
  • 在 Django 中使用 prefetch_lated 连接 ManyToMany 字段

    我可能遗漏了一些明显的东西 但我在连接 ManyToMany 字段以在 Django 应用程序中工作时遇到问题 我有两个模型 class Area models Model name CharField class Role models
  • Huggingface 变形金刚模块未被 anaconda 识别

    我正在使用 Anaconda python 3 7 Windows 10 我尝试通过安装变压器https huggingface co transformers https huggingface co transformers 在我的环境
  • 如何在python 2.7.8中将非英文字母的字典写入文件?

    这是一个简单的例子 test location 北京 country 中国 the values are Chinese 在文件 test log 中 location 北京 country 中国 在python 2 7 8中 当我需要输出
  • Django“模型”对象不可迭代

    我有一张表 其中显示了已注册的员工 我想根据他们的数据库生成一个简单的 HTML 页面 其中包括他们的姓名 id 职称等 为此 我将一个 id 传递给视图 以便它可以获取相应用户的详细信息并向我显示 一切正常 直到出现错误对象不可迭代 下面
  • 完全定制的Python帮助用法

    我正在尝试使用 Python 创建完全自定义的 帮助 用法 我计划将其导入到许多我想要具有风格一致性的程序中 但遇到了一些麻烦 我不知道为什么我的描述忽略换行符 尝试过 和 我无法让 出现在 ARGS 行的 换行符之后 显然它们坐在自己的行
  • 使用 argparse 指定默认文件名,但不使用 --help 打开它们?

    假设我有一个对文件执行一些操作的脚本 它在命令行上获取此文件的名称 但如果未提供 则默认为已知文件名 content txt 说 与蟒蛇的argparse 我使用以下内容 parser argparse ArgumentParser des
  • Django Rest Framework 序列化器中的聚合(和其他带注释的)字段

    我正在尝试找出添加带注释字段的最佳方法 例如将任何聚合 计算 字段添加到 DRF 模型 序列化器 我的用例只是一种情况 端点返回的字段未存储在数据库中 而是从数据库计算得出 让我们看下面的例子 模型 py class IceCreamCom
  • 为什么最简单的 requests_mock 示例在 pytest 中失败?

    我有一个特殊的问题requests mock 我想用它pytest测试我的 API 包装器库 我尝试过使用requests mock 文档中的第一个示例 http requests mock readthedocs io en latest
  • 保存游戏最高分?

    我使用 pygame 在 python 中制作了一个非常简单的游戏 分数取决于玩家达到的级别 我将级别作为变量称为score 我想在游戏开始或结束时显示顶级 我会更乐意显示多个分数 但我见过的所有其他线程都太复杂 我无法理解 所以请保持简单
  • Tkinter 如何根据此组合框自动更新第二个组合框

    我在 Tkinter Python 中遇到了组合框更新的问题 我有两个组合框 组合框A with values A B C and 组合框B 我想要的是 当值A在组合框中选择A然后在组合框中B显示值 1 2 3 当值B在组合框中选择A然后在
  • 如何连接多个字符串? [复制]

    这个问题在这里已经有答案了 如何将 stringList 中的所有字符串合并为一个而不打印它 例如 s joinStrings very hot day returns string print s Veryhotday 感觉有点倒退 但是
  • 对 Python 列表元素进行分组

    我有一个 python 列表 如下所示 my list 25 1 0 65 25 3 0 63 25 2 0 62 50 3 0 65 50 2 0 63 50 1 0 62 我想根据以下规则对它们进行排序 1 gt 0 65 0 62 l
  • python 相当于 sed

    有没有一种方法 无需双循环即可完成以下 sed 命令的操作 Input Time Banana spinach turkey sed i Banana s Toothpaste file Output Time BananaToothpas
  • 设置字符串中单词或字符数的限制

    假设我有一个字符串元素列表 wordlist hi what s up home diddle mc doo Oh wise master kakarot hello have a da 我希望列表中的每个元素最多包含 3 个单词或 20
  • 将同一 numpy 数组的两个视图组合成单个视图而不复制数组?

    我有一个大型 2d numpy 数组 我想删除它的子集并处理函数剩下的内容 我需要对许多子集执行此操作 因此理想情况下我不想每次都创建数组的副本 该函数不会更改数组中的任何值 mat np load filename mat 1 mat i
  • 将 .parquet 编码为 io.Bytes

    目标 将 Parquet 文件上传到 MinIO 这需要将文件转换为字节 我已经能够做到这一点了 csv json and txt bytes data to csv encode utf 8 bytes json dumps self d
  • 如何继承并重写 django 模型类来创建 listOfStringsField?

    我想为 django 模型创建一个新类型的字段 它基本上是一个 ListOfStrings 因此 在您的模型代码中 您将具有以下内容 模型 py from django db import models class ListOfString

随机推荐