Priority Queue
Source and Output
"""Example: priority queue serving jobs in priority order."""
from asimpy import Environment, PriorityQueue, Process
from _util import example
SERVICE_DURATION = 2 # ticks to process each job
# Each entry is (priority, label): lower priority number is served first.
JOBS = [
(3, "low-A"),
(1, "high-B"),
(2, "mid-C"),
(1, "high-D"),
]
class Submitter(Process):
"""Submits all jobs at t=0 then stops."""
def init(self, queue):
self._queue = queue
async def run(self):
for priority, label in JOBS:
self._env.log("submitter", f"submit ({priority}, {label})")
await self._queue.put((priority, label))
class Server(Process):
"""Processes jobs one at a time in priority order."""
def init(self, queue):
self._queue = queue
async def run(self):
while True:
priority, label = await self._queue.get()
self._env.log("server", f"start ({priority}, {label})")
await self.timeout(SERVICE_DURATION)
self._env.log("server", f"finish ({priority}, {label})")
def main():
env = Environment()
queue = PriorityQueue(env)
Submitter(env, queue)
Server(env, queue)
env.run()
return env
if __name__ == "__main__":
example(main)
| time | name | event |
|---|---|---|
| 0 | submitter | submit (3, low-A) |
| 0 | submitter | submit (1, high-B) |
| 0 | submitter | submit (2, mid-C) |
| 0 | submitter | submit (1, high-D) |
| 0 | server | start (1, high-B) |
| 2 | server | finish (1, high-B) |
| 2 | server | start (1, high-D) |
| 4 | server | finish (1, high-D) |
| 4 | server | start (2, mid-C) |
| 6 | server | finish (2, mid-C) |
| 6 | server | start (3, low-A) |
| 8 | server | finish (3, low-A) |
Key Points
-
PriorityQueueis a drop-in replacement forQueuethat serves items in ascending sorted order rather than arrival order. Items must be comparable. -
Tuples compare lexicographically in Python, so
(priority, label)pairs are ordered first by priority number and then by label string. Wrapping jobs in a tuple is a simple way to attach a priority. -
All four jobs are submitted at t=0. The server picks the smallest tuple each time:
(1, "high-B")before(1, "high-D")(same priority, earlier alphabetically) before(2, "mid-C")before(3, "low-A"). -
Arrival order has no effect once items are in the queue:
(3, "low-A")was submitted first but served last.
Check for Understanding
If you changed the label "high-B" to "high-Z", would (1, "high-D") or
(1, "high-Z") be served first, and why?