Background
Reading SimPy Shared Resources where with
statement is used to acquire resources shared among multiple running SimPy processes.
The car will now drive to a battery charging station (BCS) and request one of its two charging spots. If both of these spots are currently in use, it waits until one of them becomes available again. It then starts charging its battery and leaves the station afterwards:
def car(env, name, bcs, driving_time, charge_duration):
# Simulate driving to the BCS
yield env.timeout(driving_time)
# Request one of its charging spots
print('%s arriving at %d' % (name, env.now))
with bcs.request() as req: # <-----
yield req
# Charge the battery
print('%s starting to charge at %s' % (name, env.now))
yield env.timeout(charge_duration)
print('%s leaving the bcs at %s' % (name, env.now))
Apparently the with
block should be working as a monitor (like synchronized
in Java) so that only limited number of SimPy processes can execute inside, and the resource will be released when an exception is caused inside.
Question
Does Python with
itself provide a synchronization monitor, or SimPy Resource implements it?
Looked into the PEP 343 but was not able to follow the discussion in the PEP to figure out the answer.
with locked(myLock):
# Code here executes with myLock held. The lock is
# guaranteed to be released when the block is left (even
# if via return or by an uncaught exception).
Monitor thread synchronization in python and Lock Objects suggest a user implementation using some locking mechanism is still needed to implement a monitor in Python.
There is no python language construct for Java's synchronized (but I guess it could be built using decorators)
lock = Lock()
...
with (lock):
# This code will only be executed by one single thread at a time
# the lock is released when the thread exits the 'with' block
...