import random
import simpy
# Create a brain for the fungus to infect
class Brain(object):
def __init__(self, **kwargs): # This step allows the class to adopt any attribute defined within the model
self.__dict__.update(kwargs)
def devFungus(brain, env): # Background, organic development of brain fungus occurs at a random time
t_Fungus = random.normalvariate(5000, 100) # This is the random time for developing brain fungus naturally
try: # Develop fungus naturally
yield env.timeout(t_Fungus)
print(env.now, 'Developed fungus naturally')
brain.fungusStatus = 1 # Set the fungal status of the 'brain' object to '1'
brain.time_fungus = env.now # Record the time that the fungus grew
env.exit() # Stop running Simpy
except simpy.Interrupt: # But if aliens give you brain fungus first...
print(env.now, 'You got headshrooms from aliens')
brain.fungusStatus = 1
brain.time_fungus = env.now
env.exit() # Stop running Simpy
def randFungus(brain, env): # Fungus implanted by aliens
while True:
yield env.timeout(random.normalvariate(2000,200)) # After some period of time, aliens kidnap you and give you brain fungus
fungusDev = env.process(devFungus(brain, env)) # Interrupt the natural fungus development function
fungusDev.interrupt()
break # Aliens leave, their dastardly work finished
brain = Brain() # Create a brain
env = simpy.Environment() # Run the functions
env.process(devFungus(brain, env))
env.process(randFungus(brain, env))
env.run()(2088.5308414906685, 'You got headshrooms from aliens')
(4832.6423522407895, 'Developed fungus naturally')
vars(brain)Out[10]: {'fungusStatus': 1, 'time_fungus': 4832.6423522407895}
def devFungus(brain, env):
... # same, but remove the `env.exit()` calls--they are superfluous
def randFungus(brain, env, devFungProc):
yield env.timeout(random.normalvariate(...))
if not devFungProc.triggered:
devFungProc.interrupt()
brain = brain()
env = simpy.Environment()
devFungProc = env.process(devFungus(brain, env))
env.process(randFungus(brain, env, devFungProc))
env.run()import random
import simpy
def fungus(env):
background_event = env.timeout(random.normalvariate(5000, 100))
alien_event = env.timeout(random.normalvariate(2000, 200))
events = yield background_event | alien_event
if background_event in events and alien_event in events:
print(env.now, "Simultaneous fungus!")
elif background_event in events:
print(env.now, "Developed fungus naturally")
else:
assert alien_event in events
print(env.now, "Alien headshrooms")
env = simpy.Environment()
env.process(fungus(env))
env.run()Hi Sebastian,It would help me if you could provide a code sample that illustrates the problem you’re working on. I’d like to understand where simpy’s interrupt mechanism is behaving differently than you expect.Thanks,Pete
--You received this message because you are subscribed to the Google Groups "python-simpy" group.To unsubscribe from this group and stop receiving emails from it, send an email to python-simpy...@googlegroups.com.To post to this group, send email to python...@googlegroups.com.To view this discussion on the web visit https://groups.google.com/d/msgid/python-simpy/d06e8122-a9c1-4657-89a4-8462f17a208f%40googlegroups.com.For more options, visit https://groups.google.com/d/optout.
import simpyimport randomrandom.seed(1)class electricBus(object):def __init__(self, env, name):self.env = envself.name = nameself.SOC = 1. #State of Charge of the bus' battery (in %)self.randomTrip = random.randint(0,30) #generate random Trip times, including initial waitself.randomLayover = 0 #generate random Layover timesself.queueEntry = 1000 #variable recording when a bus enters the charger queuedriveProc = self.env.process(self.drive_proc()) #start main processinterruptProc = self.env.process(self.interrupt_proc()) #start secondary process responsible for interrupting and eventually monitoringdef interrupt_proc(self):while True:if (int(self.queueEntry) + int(self.randomLayover)) == self.env.now:self.env.process(self.charge_proc()).interrupt()# print self.env.now, self.name, "CHARGING INTERRUPTED"self.queueEntry = 0self.randomLayover = 0yield self.env.timeout(1)def drive_proc(self):yield self.env.timeout(self.randomTrip) #wait some time before 1st tripprint self.env.now, self.name, "STARTS ITS FIRST TRIP NOW"while True:self.randomTrip = random.randint(20,30)print self.env.now, self.name, "Starts Trip lasting %s minutes with a SOC = %.3f" % (self.randomTrip, self.SOC)yield self.env.timeout(self.randomTrip) # "Drive" a trip lasting 20-30 minutesself.SOC -= (float(self.randomTrip)/200) #deduct consumed energy from Battery, assuming 0.5%/minute drivenprint self.env.now, self.name, "Completes Trip lasting %s minutes with a SOC = %.3f" % (self.randomTrip, self.SOC)if self.SOC < 0.9: #go charge if the Battery is below 90%yield self.env.process(self.charge_proc())def charge_proc(self):self.queueEntry = self.env.now #record the time a bus enters the 'queue'self.randomLayover = random.randint(5,10) #generate random layover time before next trip, during which the EB can chargeprint self.env.now, self.name, "has %s minute Layover before the next trip" % (self.randomLayover)with EBCS.request() as req:try:yield reqprint self.env.now, self.name, "STARTS CHARGING for %s minutes with a SOC = %.3f" % (self.randomLayover, self.SOC)yield self.env.timeout(self.randomLayover)self.SOC += (float(self.randomLayover)/100) # add back energy to Batteryprint self.env.now, self.name, "FINISHED CHARGING after %s minutes with a SOC = %.3f" % (self.randomLayover, self.SOC)self.queueEntry = 0self.randomLayover = 0except simpy.Interrupt:print self.env.now, self.name, "got interrupted!"self.queueEntry = 0self.randomLayover = 0env = simpy.Environment()EBCS = simpy.PreemptiveResource(env, capacity = 1) #Electric Battery Charging System resource, with 1 charging stationbus1 = electricBus(env, 'bus1')bus2 = electricBus(env, 'bus2')# bus3 = electricBus(env, 'bus3')# bus4 = electricBus(env, 'bus4')# bus5 = electricBus(env, 'bus5')env.run(until=720) #run for half a dayprint" SIMULATION COMPLETE"
Hi Sebastian,It would help me if you could provide a code sample that illustrates the problem you are working on. I would like to understand where simpy’s interrupt mechanism is behaving differently than you expect.Thanks,PeteOn Wed, May 15, 2019, at 6:19 PM, Peter Grayson wrote:
Hi Sebastian,It would help me if you could provide a code sample that illustrates the problem you’re working on. I’d like to understand where simpy’s interrupt mechanism is behaving differently than you expect.Thanks,PeteOn Wed, May 15, 2019, at 11:49 AM, Seb Brown wrote:
Bit late, but perhaps someone has figured this out.I am facing the exact same problem as the OP, namely that, although Process A was succesfully interrupted by Process B, as evidenced by the printing of a corresponding statement in the "Except simpy.Interrupt:" section, the supposedly interrupted Process A continues to run and execute all timeouts, prints, etc,. The solution suggested by Pete did not apply in my case, as there was only 1 instance of Process A being executed.Is anyone aware of a method to specifically interrupt a timeout event, or to interrupt a process altogether?Cheers,Sebastian
--You received this message because you are subscribed to the Google Groups "python-simpy" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python...@googlegroups.com.
class ElectricBus:
def __init__(self, env, ...):
...
self.charge_proc = None
self.drive_loop()
self.interrupt_loop()
def drive_loop(self):
...
while True:
...
if ...:
self.charge_proc = self.env.process(self.charge())
yield self.charge_proc
self.charge_proc = None
def interrupt_loop(self):
while True:
...
if ... and self.charge_proc is not None:
self.charge_proc.interrupt()
...
def charge(self):
...
try:
...
except Interrupt:
...