Back to Claude Scientific Skills

SimPy Shared Resources

scientific-skills/simpy/references/resources.md

2.38.07.2 KB
Original Source

SimPy Shared Resources

This guide covers all resource types in SimPy for modeling congestion points and resource allocation.

Resource Types Overview

SimPy provides three main categories of shared resources:

  1. Resources - Limited capacity resources (e.g., gas pumps, servers)
  2. Containers - Homogeneous bulk materials (e.g., fuel tanks, silos)
  3. Stores - Python object storage (e.g., item queues, warehouses)

1. Resources

Model resources that can be used by a limited number of processes at a time.

Resource (Basic)

The basic resource is a semaphore with specified capacity.

python
import simpy

env = simpy.Environment()
resource = simpy.Resource(env, capacity=2)

def process(env, resource, name):
    with resource.request() as req:
        yield req
        print(f'{name} has the resource at {env.now}')
        yield env.timeout(5)
        print(f'{name} releases the resource at {env.now}')

env.process(process(env, resource, 'Process 1'))
env.process(process(env, resource, 'Process 2'))
env.process(process(env, resource, 'Process 3'))
env.run()

Key properties:

  • capacity - Maximum number of concurrent users (default: 1)
  • count - Current number of users
  • queue - List of queued requests

PriorityResource

Extends basic resource with priority levels (lower numbers = higher priority).

python
import simpy

env = simpy.Environment()
resource = simpy.PriorityResource(env, capacity=1)

def process(env, resource, name, priority):
    with resource.request(priority=priority) as req:
        yield req
        print(f'{name} (priority {priority}) has the resource at {env.now}')
        yield env.timeout(5)

env.process(process(env, resource, 'Low priority', priority=10))
env.process(process(env, resource, 'High priority', priority=1))
env.run()

Use cases:

  • Emergency services (ambulances before regular vehicles)
  • VIP customer queues
  • Job scheduling with priorities

PreemptiveResource

Allows high-priority requests to interrupt lower-priority users.

python
import simpy

env = simpy.Environment()
resource = simpy.PreemptiveResource(env, capacity=1)

def process(env, resource, name, priority):
    with resource.request(priority=priority) as req:
        try:
            yield req
            print(f'{name} acquired resource at {env.now}')
            yield env.timeout(10)
            print(f'{name} finished at {env.now}')
        except simpy.Interrupt:
            print(f'{name} was preempted at {env.now}')

env.process(process(env, resource, 'Low priority', priority=10))
env.process(process(env, resource, 'High priority', priority=1))
env.run()

Use cases:

  • Operating system CPU scheduling
  • Emergency room triage
  • Network packet prioritization

2. Containers

Model production and consumption of homogeneous bulk materials (continuous or discrete).

python
import simpy

env = simpy.Environment()
container = simpy.Container(env, capacity=100, init=50)

def producer(env, container):
    while True:
        yield env.timeout(5)
        yield container.put(20)
        print(f'Produced 20. Level: {container.level}')

def consumer(env, container):
    while True:
        yield env.timeout(7)
        yield container.get(15)
        print(f'Consumed 15. Level: {container.level}')

env.process(producer(env, container))
env.process(consumer(env, container))
env.run(until=50)

Key properties:

  • capacity - Maximum amount (default: float('inf'))
  • level - Current amount
  • init - Initial amount (default: 0)

Operations:

  • put(amount) - Add to container (blocks if full)
  • get(amount) - Remove from container (blocks if insufficient)

Use cases:

  • Gas station fuel tanks
  • Buffer storage in manufacturing
  • Water reservoirs
  • Battery charge levels

3. Stores

Model production and consumption of Python objects.

Store (Basic)

Generic FIFO object storage.

python
import simpy

env = simpy.Environment()
store = simpy.Store(env, capacity=2)

def producer(env, store):
    for i in range(5):
        yield env.timeout(2)
        item = f'Item {i}'
        yield store.put(item)
        print(f'Produced {item} at {env.now}')

def consumer(env, store):
    while True:
        yield env.timeout(3)
        item = yield store.get()
        print(f'Consumed {item} at {env.now}')

env.process(producer(env, store))
env.process(consumer(env, store))
env.run()

Key properties:

  • capacity - Maximum number of items (default: float('inf'))
  • items - List of stored items

Operations:

  • put(item) - Add item to store (blocks if full)
  • get() - Remove and return item (blocks if empty)

FilterStore

Allows retrieval of specific objects based on filter functions.

python
import simpy

env = simpy.Environment()
store = simpy.FilterStore(env, capacity=10)

def producer(env, store):
    for color in ['red', 'blue', 'green', 'red', 'blue']:
        yield env.timeout(1)
        yield store.put({'color': color, 'time': env.now})
        print(f'Produced {color} item at {env.now}')

def consumer(env, store, color):
    while True:
        yield env.timeout(2)
        item = yield store.get(lambda x: x['color'] == color)
        print(f'{color} consumer got item from {item["time"]} at {env.now}')

env.process(producer(env, store))
env.process(consumer(env, store, 'red'))
env.process(consumer(env, store, 'blue'))
env.run(until=15)

Use cases:

  • Warehouse item picking (specific SKUs)
  • Job queues with skill matching
  • Packet routing by destination

PriorityStore

Items retrieved in priority order (lowest first).

python
import simpy

class PriorityItem:
    def __init__(self, priority, data):
        self.priority = priority
        self.data = data

    def __lt__(self, other):
        return self.priority < other.priority

env = simpy.Environment()
store = simpy.PriorityStore(env, capacity=10)

def producer(env, store):
    items = [(10, 'Low'), (1, 'High'), (5, 'Medium')]
    for priority, name in items:
        yield env.timeout(1)
        yield store.put(PriorityItem(priority, name))
        print(f'Produced {name} priority item')

def consumer(env, store):
    while True:
        yield env.timeout(5)
        item = yield store.get()
        print(f'Retrieved {item.data} priority item')

env.process(producer(env, store))
env.process(consumer(env, store))
env.run()

Use cases:

  • Task scheduling
  • Print job queues
  • Message prioritization

Choosing the Right Resource Type

ScenarioResource Type
Limited servers/machinesResource
Priority-based queuingPriorityResource
Preemptive schedulingPreemptiveResource
Fuel, water, bulk materialsContainer
Generic item queue (FIFO)Store
Selective item retrievalFilterStore
Priority-ordered itemsPriorityStore

Best Practices

  1. Capacity planning: Set realistic capacities based on system constraints
  2. Request patterns: Use context managers (with resource.request()) for automatic cleanup
  3. Error handling: Wrap preemptive resources in try-except for Interrupt handling
  4. Monitoring: Track queue lengths and utilization (see monitoring.md)
  5. Performance: FilterStore and PriorityStore have O(n) retrieval time; use wisely for large stores