4 ms·
This code creates that error by trying to wait in two threads in two loops. If the future is finished, it is fine to wait for it. Having multiple loops waiting
by vii 6y ago
This code creates that error by trying to wait in two threads in two loops. If the future is finished, it is fine to wait for it.
Having multiple loops waiting for each other is pretty complex to debug.
import asyncio
import threading
future = None
def p(msg):
print(f"{msg}: {threading.get_ident()}, event loop: {id(asyncio.get_running_loop())}")
async def one_time_setup():
p('one_time_setup start')
await asyncio.sleep(1)
p('one_time_setup done')
async def maybe_initialize():
global future
if not future:
future = asyncio.create_task(one_time_setup())
p('waiting start')
await future
p('waiting done')
def worker():
new_loop = asyncio.new_event_loop()
asyncio.set_event_loop(new_loop)
new_loop.run_until_complete(maybe_initialize())
number_of_threads = 2
for _ in range(number_of_threads):
threading.Thread(target=worker).start()
this prints
RuntimeError: Task <Task pending coro=<maybe_initialize() running at test.py:20> cb=[_run_until_complete_cb() at /Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.7/lib/python3.7/asyncio/base_events.py:158]> got Future <Task pending coro=<one_time_setup() running at test.py:11> cb=[<TaskWakeupMethWrapper object at 0x10cafdeb8>()]> attached to a different loop