[Python] asyncio

개발/Python 2017. 2. 10. 10:31
반응형

서버 한대에 SSH로 붙어서, 여러개의 원격 서버에 request를 해야 하는 일이 생겼는데,

SSH를 매번 붙여서 하기엔 SSH접속이 너무 느려서, async하게 처리하는 방법을 찾던 중,

coroutine이라는 비동기 처리를 할 수 있는 기능이 있다는 것을 알았다.


다만, python에서 제공하는 비동기 처리는 GIL (global interpreter lock)이라고 해서, lock이 존재하기 때문에 비동기 처리 같지 않은 비동기처리라고 많이 불리고 있었다. 


이런 문제점을 해결하기 위해 Python 3.4 버전이상부터 사용할 수 있는 asyncio(https://docs.python.org/3/library/asyncio.html)라는 lib가 있어서, 사용법에 대해 간단히 설명을 하고자 한다. (이 기능때문에 Python 2.7에서 3.4 이상 버전으로 갈아탈 준비를 하고 있다.)


일단 설치는 pip로 가능하다.

$ pip install asyncio


아래는 예제소스인데, 이 포스팅에서는 정말 간단한 기능만 다루기 때문에 (실제로도 간단한 기능만 사용했고;;),

상세한 정보 획득을 위해선 공식 홈을 참조하는 게 좋다. https://docs.python.org/3/library/asyncio.html

예제소스에서는 asyncio에서 사용하는 event_loop를 초기화해서, print찍는 부분을 async하게 동작하도록 해볼 생각이다.

import asyncio

@asyncio.coroutine
def print_string(str):
    print(str)

    # 아래와 같이 텀을 두지 않으면, 동시에 여러개의 Thread를 생성하면서 초기화하는 과정에서, 문제가 발생한다.
    yield from asyncio.sleep(0.1)

@asyncio.coroutine
def print_all():
    strs = ['a', 'b', 'c']

    # coroutine기반의 Task를 생성한다.
    fetches = [asyncio.Task(print_string(str)) for str in strs]  

    # asyncio에 Task들을 등록한다.
    yield from asyncio.gather(*fetches)

def main():
    # Event Loop를 초기화 한 후 coroutine으로 돌릴 메서드를 지정하여, 완료될때까지 loop한다.
    asyncio.get_event_loop().run_until_complete(print_all()) 

if __init__ == '__main__':
    main()


반응형
,