Simpy没有释放资源 - 我做错了什么?

时间:2016-09-08 16:25:03

标签: python simpy

我已经简化了代表问题的代码,并尝试调试。

以下是仍然包含错误的代码的最简单版本:

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上没有其他资源可以被占用。

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

2 个答案:

答案 0 :(得分:2)

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

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

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

var fetchModule = require("fetch");

 var Observable = require("data/observable").Observable;

 var ObservableArray = require("data/observable-array").ObservableArray;

 var data;

 var person;

 var priceFromResponse;


     function ModelViewModel() {

      var viewmodel = new Observable();

      var Viewmodel =new Observable();

           viewmodel.get=function(model){

           data = model;

           }

     var viewModel = new ObservableArray();

            viewModel.load = function() {


            fetch("http://10.0.2.2:8000/get_model", {

            method: "POST",

            headers: { "Content-Type": "application/json" },

            body: JSON.stringify({
                     brand: data,
            })  
            }).then(r => { return r.json(); }).then(function (data) {  

           for(var i=0;i<data.length;i++){

                viewModel.push({
                model: data[i].product,

                 });  

             };  

             priceFromResponse =data[0].value;


            }).then(function(price){ 

            })

            }

            viewModel.empty = function() {
            while (viewModel.length) {
            viewModel.pop();
            } 
            };

            **Viewmodel.set("price",priceFromResponse);**

           return [viewModel,viewmodel,Viewmodel];

}

module.exports = ModelViewModel;

这里有一台机器不断尝试加载,但等待它为空。加载后,它会尝试运行10秒进程,然后释放资源以允许再次加载。在100个时间步骤中,它显然可以制作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:
            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)

似乎该版本不起作用,因为它指的是第二个请求。诊断这一点可以找到一种解决方法,但知道正确的方法会很好!

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

>>> 
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)

可能就足够了,除非你有可能发布尚未被要求的东西。

基于Stefan Scherfke's评论的更新,是将请求显式传递给新进程:

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

这确实按预期工作。

答案 1 :(得分:0)

解决了 - 资源中有一个拼写错误。

最初定义为:

resource = simpy.Resource(env, 1)

正确的定义:

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