Model resources over multiple environments

283 views
Skip to first unread message

nils boudenoodt

unread,
Apr 10, 2016, 3:22:19 PM4/10/16
to python-simpy
Dear all,

I am currently facing a problem using resources that I have created in my environment env1 ( res = simpy.Resource(env1) )

When I create a second environment env2, I want to be able to also use the resource in this environment.

With the current Simpy package I am bound to my env1 after calling and yielding the resource. 
More specifically after the resource is yielded in env1, I cannot change my env2 with for example an env2.timeout() - function. 
The only manipulation that can be done is to env1 until I release my resource again in env1. After release of the resource I can again change my env2.

Does any1 know a way to bypass this or create a resource that is usable in 2 environments?
I have tried to copy resources or whole environments but nothing helps... 

Hope you guys can help!
Thank you in advance! 


Nils

Stefan Scherfke

unread,
Apr 11, 2016, 3:11:56 AM4/11/16
to nils boudenoodt, python-simpy
Hi Nils,

different environments are completely separated from another. There is no
way to move any entities from one environment into another or event use one
entity in two environments.

Doing so would result in many problems, bugs and strange behavior.

What is the specific use-case that your are trying to solve?

Cheers,
Stefan
> --
> 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/e3972c63-f24e-4caa-a4af-92a08e316e51%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Message has been deleted

nils boudenoodt

unread,
Apr 11, 2016, 3:11:52 PM4/11/16
to python-simpy

Hi Stefan,


Thank you for your quick respons ! I actually am running sub environments inside a general environment. I need the subenvironments because I have to perform 2 activities at the same time relative to the general environment. 

So before the activities, I generate 2 subenvironments an perform the activities seperately (by just using timeout functions). 

After the subenvironments are run, I delay my general environment with the longest activity duration and move on...


For these subenvironments I need to use or call upon the same resource as used previously in the general environment.


Any ideas on how I can fix this ? Either make the resource shareable over environments (which you claimed is impossible) or change the way the 2 activities can be processed at the same time only using the general environment.. I thought of multithreading, but I guess this will mess up my general environment


Thank you in advance,
Nils

Stefan Scherfke

unread,
Apr 11, 2016, 5:33:30 PM4/11/16
to nils boudenoodt, python-simpy

> Am 2016-04-11 um 21:10 schrieb nils boudenoodt <nilsbou...@gmail.com>:
>
> Hi Stefan,
>
>
>
> Thank you for your quick respons ! I actually am running sub environments inside a general environment. I need the subenvironments because I have to perform 2 activities at the same time relative to the general environment.
>
> So before the activities, I generate 2 subenvironments an perform the activities seperately (by just using timeout functions).
>
> After the subenvironments are run, I delay my general environment with the longest activity duration and move on...
>
>
>
> For these subenvironments I need to use or call upon the same resource as used previously in the general environment.
>


You don't need multiple envs for this. Just run multiple process in the same
environment.


>
>
> Any ideas on how I can fix this ? Either make the resource shareable over environments (which you claimed is impossible) or change the way the 2 activities can be processed at the same time only using the general environment.. I thought of multithreading, but I guess this will mess up my general environment
>
>
>
> Thank you in advance,
> Nils
>
>
> Op maandag 11 april 2016 09:11:56 UTC+2 schreef Stefan Scherfke:
> To view this discussion on the web visit https://groups.google.com/d/msgid/python-simpy/759c9e8f-b66a-4580-afb5-64178c005b16%40googlegroups.com.

nils boudenoodt

unread,
Apr 15, 2016, 1:11:06 PM4/15/16
to python-simpy
 Stefan,

thank you for the reply, but How can I simulate processes at the same time? :)

Can you please provide an example on how I can simultaneously run multiple processes that use one same resource?

Suppose your environment is at t=10 before you need to perform the 2 processes that start at the same time: following code will not allow correct processing because the resource that is requested delays the same environment

env = simpy.Environment()
res = simpy.Resource(env)

#simulate activity1:                           # env starts at t=10
use = res.request                              # res placed in queue, suppose queuetime = 5
yield use                                           # res assigned to environment, env delayed  env.now = 15
durationAct1=5                                  # Suppose activity 1 takes 5 time units to be processed, env not yet delayed

#simulate activity2:                           # env starts at t=15, not at t=10
use = res.request                              # res placed in queue, suppose queuetime = 5
yield use                                           # res assigned to environment, env delayed  env.now = 20
durationAct2 = 10                              # Suppose activity 2 takes 10 time units to be processed, env not yet delayed

if durationAct1<=durationAct2:
       env.timeout(durationAct2)            #environment delayed, env.now will result in 30, not 25
else:
       env.timeout(durationAct1)


As you can see the processes are not run simultaneously. Due to queueing, the environment itself will be delayed before the activities are performed. This causes a shift of 5 time units due to delay in the other activity. 
Just removing the yield function and actually the entire activity 1 can fix this problem, but I want to be able to simulate the general case where activity1 takes longer than activity2 or vice versa.

Please advice on how I can fix this.

Best regards and thx for the help!

jpgr...@gmail.com

unread,
Apr 15, 2016, 1:57:18 PM4/15/16
to python-simpy
The way you are using the resource is a bit odd. Typically, you acquire a Resource in order to allow one process exclusive access to that resource. In your case, however, you have two processes that you are saying need to acquire the resource, but also run in parallel. I have to assume there is another process besides activity1 and activity2 that you want to block while the resource is in-use by activity1 and/or activity2--otherwise you would not need a Resource at all.

Consider an approach where you have another process that encapsulates activity1 and activity2 processes and manages the resource:

def activity1(env):
   
... # whatever activity1 does
   
yield env.timeout(5)

def activity2(env):
   
... # whatever activity2 does
   
yield env.timeout(10)

def activity_1_2_chooser(env, res):
   
with res.request() as req:
       
yield req
        a1
= env.process(activity1(env))
        a2
= env.process(activity2(env))
       
yield a1 | a2
   
# res is released here upon *either* activity1 or activity2 completing
   
# env.now will reflect the shorter of the two activities' durations

nils boudenoodt

unread,
Apr 15, 2016, 3:35:12 PM4/15/16
to python-simpy
Thanks for the quick response,

I think I still need to clarify it a little bit further

Suppose we define 2 people as resource (people = simpy.Resource(env,capacity=2)). I want to run 2 activities within the same process and environment (env), with 1 person performing 1 activity and the other person performing the other activity. How will you implement this when you want the 2 persons to start the activities at the same time. 

The code mentioned above does not take into account that the second activity also requires a resource. 

Ideally, to come back to my example, the env is at time 10, activity 1 and activity 2 request a person and are placed in queue (suppose activity1 before activity2-doesnt matter). 
At time 15, 2 resources become available again and are yielded to both activities. Both activities are started and activity 1 ends at time 20 and releases person1. Activity 2 ends at time 25 and releases person 2 to the environment.

Activity 1 or 2 might be queued a bit longer, but the processing overlaps in order to perform both activities simultaneously. 

How can this be made possible with Simpy?

Best regards,
Nils

jpgr...@gmail.com

unread,
Apr 15, 2016, 9:19:23 PM4/15/16
to python-simpy
This is the best I can do given the problem description. The `ready_events` are not explicitly required to achieve the desired behavior in this scenario, but I include them anyway to illustrate a potentially useful mechanism for processes to communicate their mutual readiness. I'll also note that `other_stuff` could have alternatively been modeled with a Resource with capacity=2.

env = Environment(initial_time=10)
people
= Resource(env, capacity=2)
other_stuff
= Container(env)
ready_events
= [env.event(), env.event()]

def activity1(env, people, ready_events, other_stuff):
   
with people.request() as person_req:
       
yield person_req
        ready_events
[0].succeed()
       
yield ready_events[1] & other_stuff.get(1)
       
yield env.timeout(5)
   
assert env.now == 20

def activity2(env, people, ready_events, other_stuff):
   
with people.request() as person_req:
       
yield person_req
        ready_events
[1].succeed()
       
yield ready_events[0] & other_stuff.get(1)
       
yield env.timeout(10)
   
assert env.now == 25

def mysterious_other_process(env, other_stuff):
   
yield env.timeout(5)
   
yield other_stuff.put(2)

env
.process(activity1(env, people, ready_events, other_stuff))
env
.process(activity2(env, people, ready_events, other_stuff))
env
.process(mysterious_other_process(env, other_stuff))
env
.run()

 

nils boudenoodt

unread,
Apr 16, 2016, 6:03:54 AM4/16/16
to python-simpy
Hi jpgr,

Thank you again for your help! I didn't know how the environment reacted when using "&" and "|" in the code. But this gave me the answer to my problem! So thank you for all the help :)
As you can see I'm not so familiar with Simpy or Python for that matter :p


Best regards,
Nils

jpgr...@gmail.com

unread,
Apr 16, 2016, 4:48:19 PM4/16/16
to python-simpy
Great! I'm glad you are up and running.

Cheers,
Pete
Reply all
Reply to author
Forward
0 new messages