+큐가 찼을 때 바로 거절하는 동작도 비교해보자. 다음 Python 3 예제는 put_nowait을 쓰므로 두 번째 항목을 기다려 넣는 대신 QueueFull을 받아 접수하지 않았다고 알린다. 마지막에 꺼내는 값은 먼저 넣은 first다. put_nowait의 계약.
import asyncio
queue = asyncio.Queue(maxsize=1)
queue.put_nowait("first")
try:
queue.put_nowait("second")
except asyncio.QueueFull:
print("second: not accepted")
print(queue.get_nowait()) # first
같은 한 칸짜리 큐에 await put으로 넣으면 다음처럼 기다린다. Python 3.11 이상에서 실행하며, put_started로 두 번째 항목을 넣기 시작한 시점을 맞춘다. 첫 항목이 큐에 남아 있는 동안에는 두 번째 put이 완료되지 않는다.
import asyncio
async def main():
queue = asyncio.Queue(maxsize=1)
await queue.put("first")
put_started = asyncio.Event()
async def put_second():
put_started.set()
await queue.put("second")
async with asyncio.TaskGroup() as group:
pending = group.create_task(put_second())
await put_started.wait()
print(pending.done()) # False
first = await queue.get()
await pending
print(first, await queue.get()) # first second
if __name__ == "__main__":
asyncio.run(main())
첫 get이 항목을 꺼내면 생산자가 두 번째 항목을 넣을 공간이 생긴다. 여기서는 첫 항목을 꺼내 변수에 담기만 했고 별도의 업무 처리를 시작하지도 않았다. 큐의 빈칸을 기다리는 것과 소비자의 처리 완료를 기다리는 것이 어느 지점에서 갈리는지 볼 수 있다.