如何在 Simpy 模拟中结束进程

How to end a process in Simpy simulation

我是 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())

Class 资源有一个 start 和 运行 方法如下: 还假设每个资源在实例化时都有一个处理时间: 每个资源也有对其他资源的引用,不显示所有这些的代码以使其简短。

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。但是在此之后,环境 运行s 完成所有资源进程并且 env.now 更改超出了预期的第一站。

我尝试了 env.exit() 但没有成功。 simpy有什么办法可以立即停止模拟,不管什么进程被调度了。

此致

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

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

我在 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()