Skip to content

Instantly share code, notes, and snippets.

@ekzhang
Created August 16, 2023 17:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ekzhang/2461cd14ec2ba3a36655fc9610fb20a5 to your computer and use it in GitHub Desktop.
Save ekzhang/2461cd14ec2ba3a36655fc9610fb20a5 to your computer and use it in GitHub Desktop.
Demo of yield-dependent behavior when a coroutine blocks the event loop.
# Demo of yield-dependent behavior when a coroutine blocks the event loop.
#
# Vary the number of calls to asyncio.sleep(0.0) in either block, and behavior will change greatly.
#
# (4 in top block, 9 in bottom block)
# 0 3.0027458667755127
# 1 2.0022785663604736
# 2 8.320808410644531e-05
# 3 4.38690185546875e-05
# 4 3.838539123535156e-05
#
# (4 in top block, 18 in bottom block)
# 0 5.005687952041626
# 1 0.00013685226440429688
# 2 7.081031799316406e-05
# 3 7.128715515136719e-05
# 4 6.723403930664062e-05
#
# (4 in top block, 2 in bottom block)
# 0 1.0011606216430664
# 1 1.0011751651763916
# 2 1.0011844635009766
# 3 1.0011827945709229
# 4 1.0010712146759033
import asyncio
import time
async def f():
for i in range(5):
yield i
time.sleep(1)
await asyncio.sleep(0.0)
await asyncio.sleep(0.0)
await asyncio.sleep(0.0)
await asyncio.sleep(0.0)
async def main():
pre = time.time()
q = asyncio.Queue()
async def drive_generator():
async for x in f():
await q.put(x)
asyncio.create_task(drive_generator())
for _ in range(5):
x = await q.get()
await asyncio.sleep(0.0)
await asyncio.sleep(0.0)
await asyncio.sleep(0.0)
await asyncio.sleep(0.0)
await asyncio.sleep(0.0)
await asyncio.sleep(0.0)
await asyncio.sleep(0.0)
await asyncio.sleep(0.0)
await asyncio.sleep(0.0)
cur = time.time()
print(x, cur - pre)
pre = cur
asyncio.run(main())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment