I have this code snippet
import asyncio
import time
async def put_stuff_into_queue(stuff_into_queue: list[str], queue: asyncio.Queue) -> None:
for stuff in stuff_into_queue:
await queue.put(stuff)
await asyncio.sleep(1)
print(f"end time: {time.strftime('%X')}")
async def process_stuff_from_queue(queue: asyncio.Queue) -> None:
while True:
stuff: str = await queue.get()
print(stuff)
async def main() -> None:
queue = asyncio.Queue()
stuff_into_queue = ["this", "is", "a", "simple", "test"]
print(f"start time: {time.strftime('%X')}")
asyncio.create_task(put_stuff_into_queue(stuff_into_queue, queue)) # this line is never awaited
asyncio.create_task(process_stuff_from_queue(queue)) # this line is never awaited
await asyncio.sleep(8) # with this line, the previous two lines seems to be running
# time.sleep(8) # if I comment out the previous line and instead use this line, then all the tasks don't run
if __name__ == '__main__':
asyncio.run(main())
The output I receive with the code as it is above is
start time: 15:54:38
this
is
a
simple
test
end time: 15:54:43
Process finished with exit code 0
If I run with time.sleep(8)
instead of await asyncio.sleep(8)
, then my output is
start time: 15:59:09
this
Process finished with exit code 0
The console output this
occurs after sleeping for 8 seconds, so I presume it has something to with the unawaited tasks executing a single iteration once asyncio.run(main())
is done? I am not entirely sure why I only get one iteration, or why I even get an iteration of Task event loop.
Why are the two un-awaited tasks running perfectly when I have await asyncio.sleep(8)
, but not when I have time.sleep(8)
? Does it have something to do with GIL when doing time.sleep
where it somehow blocks the main loop flow?
Why are the two un-awaited tasks running perfectly when I have await asyncio.sleep(8), but not when I have time.sleep(8)?
Because that's how asyncio
works: calling await
is what yields execution back to the scheduler so that it can run other async tasks. When you call time.sleep
, you're never calling await
, so other async tasks never get the chance to run.