I am learning SimPy. Currently I need to call a method periodically until the simulation ends.
I wrote it like
import SimPy.Simulation as Simpy
class mod(Simpy.Process):
def do(self):
print(Simpy.now(), "Do!")
yield Simpy.hold, self, 5.0
class trigger(Simpy.Process):
def ACTIONS(self):
while True:
for i in self.target.do():
yield i
yield Simpy.hold, self, 1.0
def set_target(self, tar):
self.target = tar
Simpy.initialize()
obj = mod()
tri = trigger()
tri.set_target(obj)
tri.start(at=0.0)
Simpy.simulate(until=100.0)
Due to the statements in the while True:
,it should yield the target.do()
by every 1.0 time unit. Therefore the output should be:
0.0 Do!
1.0 Do!
2.0 Do!
......
But in fact, it yield the target.do()
by every 6.0 time unit (the yield
holds to wait until the target.do()
finishes):
0.0 Do!
6.0 Do!
12.0 Do!
I wonder that how can I yield the target function periodically into the schedule, without waiting until it finishes executing?
Thank you! ......
OK I figured it out by myself. A Process
in SimPy is a kind of thing as an event. Whenever it has been scheduled and then completed, it will be terminated. Therefore whenever you want to insert an event into the timeline, the instance of Process
should be a new one. In other word, the Process
should be treated as a disposable signal, instead of the working method itself.
So, the Process
should be like:
class Event(Simpy.Process):
def call_do(self, subject):
subject.do()
and the working method should no longer be a instance of Process
. the time delay should be controlled by activating event
instead of being controlled by workflow:
class mod():
def do(self):
print(Simpy.now(), "Do!")
Finally, we can schedule it like this:
while True:
e = Event()
Simpy.activate(e, e.call_do(self.target), delay = 5.0)
yield Simpy.hold, self, 1.0