SimPy Process Not Running: Why Nothing Happens
You wrote the code. You ran the simulation. Nothing happened.
Here's why—and how to fix it.
Problem 1: Process Not Started
The most common culprit:
# WRONG
def arrivals(env, server):
while True:
yield env.timeout(5)
customer(env, server) # Created but never started!
# RIGHT
def arrivals(env, server):
while True:
yield env.timeout(5)
env.process(customer(env, server)) # Now it runs
Rule: Every process needs env.process() to start.
Problem 2: Forgot to Call the Function
# WRONG
env.process(customer) # Function reference, not generator!
# RIGHT
env.process(customer(env, server)) # Call it to get generator
Rule: Call the process function. The parentheses matter.
Problem 3: No Initial Process
# WRONG
env = simpy.Environment()
# ... define processes but never start any ...
env.run(until=100) # Nothing to run!
# RIGHT
env = simpy.Environment()
env.process(arrivals(env, server)) # Start something
env.run(until=100)
Rule: At least one process must be started before run().
Problem 4: Process Exits Immediately
# WRONG - no yields, exits instantly
def customer(env, server):
print("Customer arrives")
server.request() # Missing yield!
print("Customer done") # Runs immediately
# RIGHT
def customer(env, server):
print("Customer arrives")
with server.request() as req:
yield req # Wait for resource
yield env.timeout(5) # Wait for service
print("Customer done")
Rule: Without yield, a process completes instantly.
Problem 5: Return Instead of Yield
# WRONG
def customer(env, server):
with server.request() as req:
return req # Exits function!
yield env.timeout(5) # Never reached
# RIGHT
def customer(env, server):
with server.request() as req:
yield req
yield env.timeout(5)
Rule: return exits. yield waits.
Problem 6: Condition Never Met
# WRONG - condition might never be true
def conditional_process(env, flag):
if flag: # If false, nothing yields
yield env.timeout(5)
# Process ends without yielding anything
# BETTER
def conditional_process(env, flag):
if flag:
yield env.timeout(5)
else:
yield env.timeout(0) # At least yield something
Rule: A process with no yields is just a function.
Problem 7: Waiting on Empty Store/Container
# WRONG - waits forever if store is empty
def consumer(env, store):
item = yield store.get() # Blocks if nothing there
print(f"Got {item}")
# Nobody ever puts anything in the store!
# RIGHT - ensure producer exists
env.process(producer(env, store)) # Someone must fill the store
env.process(consumer(env, store))
Rule: Get operations block until items are available.
Problem 8: Resource at Full Capacity
# All resources busy, new requests queue forever
def never_releasing(env, server):
with server.request() as req:
yield req
# Infinite loop - never releases!
while True:
yield env.timeout(1)
# Other customers wait forever
Rule: Resources must be released for others to proceed.
Problem 9: Simulation Time Too Short
# First arrival at time 100, simulation ends at time 50
def arrivals(env, server):
yield env.timeout(100) # First arrival at t=100
env.process(customer(env, server))
env.run(until=50) # Ends before any arrivals!
Rule: Run long enough for events to occur.
Problem 10: Event Never Triggered
# WRONG - event never succeeds
completion = env.event()
def worker(env):
yield completion # Waits forever
print("Done!")
# Nobody calls completion.succeed()
# RIGHT
def trigger(env, event):
yield env.timeout(10)
event.succeed() # Trigger the event
env.process(worker(env))
env.process(trigger(env, completion))
Rule: Custom events need to be triggered.
Diagnostic Checklist
When processes don't run, check:
# 1. Is the process started?
proc = env.process(my_process(env)) # ✓
# 2. Does the process yield?
def my_process(env):
yield env.timeout(1) # ✓
# 3. Is there at least one active process?
print(f"Active processes: {len(env._queue)}")
# 4. Is the simulation running long enough?
env.run(until=1000) # Long enough?
# 5. Add debug output
def my_process(env):
print(f"[{env.now}] Process starting") # See if this prints
yield env.timeout(1)
print(f"[{env.now}] Process done")
Debug Helper
def verify_process_starts(env, process_gen, name="process"):
"""Verify a process actually starts and runs."""
started = False
completed = False
def wrapper():
nonlocal started, completed
started = True
print(f"[{env.now}] {name} STARTED")
yield from process_gen
completed = True
print(f"[{env.now}] {name} COMPLETED")
proc = env.process(wrapper())
return proc, lambda: (started, completed)
# Usage
proc, status = verify_process_starts(env, customer(env, server), "customer")
env.run(until=100)
started, completed = status()
print(f"Started: {started}, Completed: {completed}")
Process Lifecycle Monitor
def monitor_processes(env, interval=10):
"""Monitor whether anything is happening."""
last_time = -1
while True:
if env.now == last_time:
print(f"WARNING: Time stuck at {env.now}")
print(f"Queue length: {len(env._queue)}")
else:
print(f"[{env.now}] Simulation progressing, queue: {len(env._queue)}")
last_time = env.now
yield env.timeout(interval)
env.process(monitor_processes(env))
Summary
Process not running? Check:
- Did you call
env.process()? - Did you call the function (with parentheses)?
- Does the process yield events?
- Is there something blocking forever?
- Is the simulation running long enough?
No yield, no process. No env.process(), no execution.
Next Steps
Strengthen Your Python Skills
If you're finding Python tricky, get up to speed quickly with the 10-Day Python Bootcamp. It's designed to give you the confidence and skills to write clean, effective code.
Start the Python Bootcamp