2

I'm working on a queuing simulation model in python 2 that has jobs coming into the system and requesting multiple resources. Each job that arrives asks for different amounts of resources (and not a specific resource!) and uses the resources for a different amount of time.

Any example of this that I find requests specific resources, like res[1] and res[2]. I just need to request 2 resources.

Also, my jobs are only running after the first job completes. I understand that there is a problem with my for loop, but I'm not sure how to fix it properly. In this case, because there are 2 resources a and b should be able to run at time 1. But b waits until a finishes. odd.

I would appreciate help with requesting the multiple resources and running the jobs at the proper time.

here is my code so far:

import simpy


#resource
class SuperComputer:
    def __init__(self, env):
        self.nodes = simpy.Resource(env, capacity = 2)


#users of resource
class Job:
    #enter: time the job enters the system
    #timeout is how long the job occupies a resource for
    #resources is how many resources a job needs in order to run
    def __init__(self, env, name, enter,timeout, resources):
        self.env = env
        self.name = name 
        self.enter = enter
        self.timeout = timeout
        self.resources = resources


#system
def system(env, jobs, super_computer):
    with super_computer.nodes.request() as req:

        for job in jobs:
            print('%s arrives at %s' % (job.name, job.enter)) 
            yield req
            yield env.timeout(job.enter)
            print('%s starts running with %s resources at %s' % (job.name, job.resources, env.now)) 
            yield env.timeout(job.timeout)
            print('%s completed job at %s' % (job.name, env.now)) 




env = simpy.Environment()
super_computer = SuperComputer(env) 

jobs = [
        Job(env, 'a', 1, 4, 1),
        Job(env, 'b', 1, 4, 1),
        Job(env, 'c', 1, 4, 1),
        Job(env, 'd', 1, 4, 1),
    ]


env.process(system(env, jobs, super_computer))    

env.run(50)        

output:

a arrives at 1
a starts running with 1 resources at 1
a completed job at 5
b arrives at 1
b starts running with 1 resources at 6
b completed job at 10
c arrives at 1
c starts running with 1 resources at 11
c completed job at 15
d arrives at 1
d starts running with 1 resources at 16
d completed job at 20
s.im
  • 21
  • 2

1 Answers1

1

The problem is that your code needs to complete one round of the for loop before moving on to the next one.

Your code works if the for loop is put outside the process, instead creating a new process for each job which allows them to operate in parallel.

import simpy


#resource
class SuperComputer:
        def __init__(self, env):
        self.nodes = simpy.Resource(env, capacity = 2)


#users of resource
class Job:
    #enter: time the job enters the system
    #timeout is how long the job occupies a resource for
    #resources is how many resources a job needs in order to run
    def __init__(self, env, name, enter,timeout, resources):
        self.env = env
        self.name = name 
        self.enter = enter
        self.timeout = timeout
        self.resources = resources


#system
def system(env, job, super_computer):
    with super_computer.nodes.request() as req:
        print('%s arrives at %s' % (job.name, job.enter)) 
        yield req
        yield env.timeout(job.enter)
        print('%s starts running with %s resources at %s' % (job.name, job.resources, env.now)) 
        yield env.timeout(job.timeout)
        print('%s completed job at %s' % (job.name, env.now)) 


env = simpy.Environment()
super_computer = SuperComputer(env) 

jobs = [
        Job(env, 'a', 1, 4, 1),
        Job(env, 'b', 1, 4, 1),
        Job(env, 'c', 1, 4, 1),
        Job(env, 'd', 1, 4, 1),
    ]


for job in jobs:
    env.process(system(env, job, super_computer))    

env.run(50)        
Harry Munro
  • 304
  • 2
  • 12
  • thank you! such an easy fix. do you have any guidance on how i can request multiple resources for different jobs? currently, if i have a job requesting 2 resources, my print function will print out what is asked, but req() isn't working if i request req(job.resources) – s.im Feb 14 '18 at 05:26
  • Sorry, slightly late reply here! Depending on how you model resources you could either sequentially request two different resources, or you could use a store or container resource and ask for 2 things from that. If you're doing the fomer I'd recommend changing your resource requests to get rid of "with" and format them like: req = resource.request resource.release(req) Makes it much easier to handle multiple resource requests. – Harry Munro Feb 09 '22 at 13:59