1
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())
1
  • 1
    There is a built-in function made exactly for that. Commented Nov 9, 2022 at 22:59

1 Answer 1

1

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())
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.