0

我是 SimPy 的新手,正在努力完成以下工作。模拟流程,每个流程都有不同的时间延迟。第一个过程完成后,我将中断我捕获的其他过程。但是一旦在 catch 块中,所有这些进程都会再次恢复,并且环境时钟会继续运行,直到所有这些进程都完成。我希望模拟在第一个进程完成后立即停止,然后更新其他进程的剩余时间并基本上停止一切,以便 env.now 时间在第一个进程完成时。

示例代码

class Main:
   env = simpy.Environment()
   res1 = Resource(env, list(), 10)
   res2 = Resource(env, list(), 15)
   res3 = Resource(env, list(), 20)
   #Add other resources to each
   res1.appendOtherResource(res2)
   res1.appendOtherResource(res3)
   res2.appendOtherResource(res1)
   res2.appendOtherResource(res3)
   res3.appendOtherResource(res2)
   res3.appendOtherResource(res1)

   Resources = list()
   Resources.append(res1)
   Resources.append(res2)
   Resources.append(res3)
   env.process(scheduleResources(Resources, env))
   env.run()
   

def scheduleResources(Resources, env)
    for resource in Resources:
        env.process(resource.start())

类 Resource 有一个 start 和 run 方法,具有以下内容: 还假设每个资源在实例化时都有一个处理时间:每个资源还具有对其他资源的引用,为了保持简短,没有显示所有代码。

class Resource:
    def __init__(self, env, otherResources, timeToProcess):
        self.resource_process = None
        self.otherResources = otherResources
        self.env = env
        self.timeToProcess = timeToProcess



def appendOtherResource(self, otherResource):
     self.otherResources.append(otherResource)

def start(self):
     yield (self.env.timeout(0))
     self.resource_process = self.env.process(self.run())

 def run(self):
    try:
        self.env.timeout(self.timeToProcess)
        self.timeToProcess = 0
        for res in self.otherResources:
            if res.resource_process != None:
                 if res.resource_process.is_alive:
                        res.resource_process.interrupt() 
     except simpy.Interrupt as interrupt:
        self.timeToProcess = self.timeToProcess - self.env.now
        #How do i ensure that the process that is interrupted is killed after this step and does not continue 

当前发生的情况是完成了最短的资源进程。对所有其他资源调用中断,并且正确更新 timeToProcess。但在此之后,环境运行以完成所有资源进程,并且 env.now 更改超出了预期的第一站。

我尝试了 env.exit() 但没有成功。simpy 中是否有任何方法可以立即停止模拟,无论安排什么进程。

问候

4

1 回答 1

1

当您调用 env.run() 模拟运行直到所有事件完成。问题是当您中断资源进程时,您的资源进程会被中断,但进程中的超时事件不会。因此您的资源进程已全部完成或被中断,但 env.run 在结束模拟之前仍在等待所有超时完成。

env.run() 有一个 until 参数。此参数可以是数字或事件。当它是一个数字时,sim 将结束的时间单位。当它是一个事件时,模拟将持续到事件触发。

我将资源进程包装在 env.all_of 事件中。此事件触发将触发其列表中的所有事件。并将其传递给 env.run

env.run(until=env.all_of(resource_processes))

我还进行了一些其他小的更改,以使您的代码运行并更好地跟踪事件

也不是说您可以通过第二次调用 env.run() 来恢复模拟

这是代码

import simpy

def scheduleResources(Resources, env):

    # start the resource process and return a list of hte processes
    process_list = []
    for resource in Resources:
        process_list.append(resource.start())

    return(process_list)

class Resource:
    def __init__(self, env, id, otherResources, timeToProcess):
        self.id = id
        self.resource_process = None
        self.otherResources = otherResources
        self.env = env
        self.timeToProcess = timeToProcess

    def appendOtherResource(self, otherResource):
        self.otherResources.append(otherResource)

    def start(self):
        #yield (self.env.timeout(0))
        self.resource_process = self.env.process(self.run())
        return self.resource_process

    def run(self):
        try:
            yield self.env.timeout(self.timeToProcess)
            self.timeToProcess = 0
            for res in self.otherResources:
                if res.resource_process != None:
                    if res.resource_process.is_alive:
                            res.resource_process.interrupt() 
            print (self.id, "finished")
        except simpy.Interrupt as interrupt:
            print(self.id, "interupted")
            self.timeToProcess = self.timeToProcess - self.env.now

def main():
    env = simpy.Environment()
    res1 = Resource(env, 1, list(), 10)
    res2 = Resource(env, 2, list(), 15)
    res3 = Resource(env, 3, list(), 20)
    #Add other resources to each
    res1.appendOtherResource(res2)
    res1.appendOtherResource(res3)
    res2.appendOtherResource(res1)
    res2.appendOtherResource(res3)
    res3.appendOtherResource(res2)
    res3.appendOtherResource(res1)

    Resources = list()
    Resources.append(res1)
    Resources.append(res2)
    Resources.append(res3)

    resource_processes = scheduleResources(Resources, env)

    # stop when all the resources process ends
    env.run(until=env.all_of(resource_processes))
    #env.run()
    print('end time', env.now)

main()
于 2022-01-19T17:34:53.680 回答