Using asyncio for Non-async Functions in Python?

前端 未结 2 375
轻奢々
轻奢々 2020-12-20 21:33

Suppose there is a library that makes various database queries:

import time

def queryFoo():
    time.sleep(4)
    return \"foo\"

def queryBar():
    time.s         


        
2条回答
  •  予麋鹿
    予麋鹿 (楼主)
    2020-12-20 21:56

    If some function is blocking and not async by nature, only proper way to run it inside asyncio event loop is to run it inside thread using run_in_executor:

    # Our example blocking functions
    import time
    
    
    def queryFoo():
        time.sleep(3)
        return 'foo'
    
    
    def queryBar():
        time.sleep(3)
        return 'bar'
    
    
    # Run them using asyncio
    import asyncio
    from concurrent.futures import ThreadPoolExecutor
    
    
    _executor = ThreadPoolExecutor(10)
    
    
    async def in_thread(func):
        loop = asyncio.get_event_loop()
        return await loop.run_in_executor(_executor, func)
    
    
    async def main():
        results = await asyncio.gather(
            in_thread(queryFoo), 
            in_thread(queryBar),
        )
    
        print(results)
    
    
    if __name__ == "__main__":
        loop = asyncio.get_event_loop()
        try:
            loop.run_until_complete(main())
        finally:
            loop.run_until_complete(loop.shutdown_asyncgens())
            loop.close()
    

    It does job.

    If you however want to avoid using threads only way to do it - is to rewrite queryFoo/queryBar to be async by nature.

提交回复
热议问题