Resource
Source and Output
"""Example: shared resource with limited capacity."""
from asimpy import Environment, Process, Resource
from _util import example
NUM_WORKERS = 4 # total number of workers competing for the resource
CAPACITY = 2 # number of concurrent slots on the shared resource
WORK_DURATION = 3 # ticks each worker spends holding the resource
class Worker(Process):
def init(self, name, resource, delay):
self._name = name
self._resource = resource
self._delay = delay
async def run(self):
await self.timeout(self._delay)
self._env.log(self._name, "request")
await self._resource.acquire()
self._env.log(self._name, "start")
await self.timeout(WORK_DURATION)
self._resource.release()
self._env.log(self._name, "done")
def main():
env = Environment()
resource = Resource(env, capacity=CAPACITY)
for i in range(NUM_WORKERS):
Worker(env, f"worker {i}", resource, delay=i)
env.run()
return env
if __name__ == "__main__":
example(main)
| time | name | event |
|---|---|---|
| 0 | worker 0 | request |
| 0 | worker 0 | start |
| 1 | worker 1 | request |
| 1 | worker 1 | start |
| 2 | worker 2 | request |
| 3 | worker 3 | request |
| 3 | worker 0 | done |
| 3 | worker 2 | start |
| 4 | worker 1 | done |
| 4 | worker 3 | start |
| 6 | worker 2 | done |
| 7 | worker 3 | done |
Key Points
-
Resource(env, capacity=N)creates a pool ofNslots. The default capacity is 1 (a mutual-exclusion lock). -
acquire()returns anEventthat resolves when a slot is available. If all slots are taken the caller blocks until another process callsrelease(). -
release()is synchronous, notasync. It immediately grants the freed slot to the first waiting process, if any. -
Workers 2 and 3 arrive while both slots are occupied and wait: worker 2 starts at t=3 when worker 0 finishes, and worker 3 starts at t=4 when worker 1 finishes.
Check for Understanding
What would happen if a process called resource.release() before awaiting its
timeout(WORK_DURATION)?
Would another process start its work sooner, later, or at the same time?