import asyncio
import time
def blocking_function():
print("Blocking function called")
time.sleep(5)
print("Blocking function finished")
async def concurrent_function():
for x in range(10):
print(x)
await asyncio.sleep(1)
async def main():
print("Main function called")
loop = asyncio.get_event_loop()
loop.run_in_executor(None, blocking_function)
await concurrent_function()
print("Main function finished")
if __name__ == "__main__":
asyncio.run(main())
When attempting to run a blocking function while asyncio code is also running, this works perfectly. However, if I have a funciton which contains blocking code (eg. a libary which is not asyncronous I am unable to do this)
Because the function contains both blocking code, and asynconrous code I cannot use run in executor
. How can I get around this?
The below code unfortunetly errors due to the blocking_function
not being awaited, but you annot use that in conjunction with run_in_executor
async def blocking_function():
for x in range(4):
print("Blocking function called")
time.sleep(1)
print("Blocking function finished")
print("Async code running:")
await asyncio.sleep(1)
print("Async code finished")
async def concurrent_function():
for x in range(10):
print(x)
await asyncio.sleep(1)
async def main():
print("Main function called")
loop = asyncio.get_event_loop()
loop.run_in_executor(None, blocking_function)
await concurrent_function()
print("Main function finished")
if __name__ == "__main__":
asyncio.run(main())
CodePudding user response:
just create an event loop in the second thread and run the async function there.
import asyncio
import time
async def blocking_function():
for x in range(4):
print("Blocking function called")
time.sleep(1)
print("Blocking function finished")
print("Async code running:")
await asyncio.sleep(1)
print("Async code finished")
def async_blocking_function_runner(func):
# creates another event loop in the other thread and runs func in it
res = asyncio.run(func())
return res
async def concurrent_function():
for x in range(10):
print(x)
await asyncio.sleep(1)
async def main():
print("Main function called")
loop = asyncio.get_event_loop()
res = loop.run_in_executor(None, async_blocking_function_runner, blocking_function)
await concurrent_function()
await res # make sure the task in second thread is done
print("Main function finished")
if __name__ == "__main__":
asyncio.run(main())