본문 바로가기

잡것들

asyncio 에서 동기 함수를 비동기함수 처럼 사용하는 법

비동기 i/o 에 대한 이해가 없다면 아래 영상을 보고 오시면 도움이 됩니다.

https://youtu.be/wB9tIg209-8

 

async 를 사용할 때 시간이 많이 걸리는 동기  함수를 사용하게 되면 다른 작업을 처리하지 뫗하는 현상이 발생한다.

이 때 run_in_executor 를 사용하게 되면 동기 함수를 비동기 함수처럼 await 로 사용할 수 있게 된다.

import asyncio
import concurrent.futures

def blocking_io():
    # File operations (such as logging) can block the
    # event loop: run them in a thread pool.
    with open('/dev/urandom', 'rb') as f:
        return f.read(100)

def cpu_bound():
    # CPU-bound operations will block the event loop:
    # in general it is preferable to run them in a
    # process pool.
    return sum(i * i for i in range(10 ** 7))

async def main():
    loop = asyncio.get_running_loop()

    ## Options:

    # 1. Run in the default loop's executor:
    result = await loop.run_in_executor(
        None, blocking_io)
    print('default thread pool', result)

    # 2. Run in a custom thread pool:
    with concurrent.futures.ThreadPoolExecutor() as pool:
        result = await loop.run_in_executor(
            pool, blocking_io)
        print('custom thread pool', result)

    # 3. Run in a custom process pool:
    with concurrent.futures.ProcessPoolExecutor() as pool:
        result = await loop.run_in_executor(
            pool, cpu_bound)
        print('custom process pool', result)

if __name__ == '__main__':
    asyncio.run(main())

 

참고 https://docs.python.org/ko/3.10/library/asyncio-eventloop.html#asyncio.loop.run_in_executor