일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 파이썬
- 스위프트
- 파이썬 강좌
- Akka
- 안드로이드 웹뷰
- 스칼라 강좌
- Golang
- play 강좌
- 파이썬 머신러닝
- 스칼라 동시성
- 스칼라
- play2 강좌
- Play2 로 웹 개발
- 그라파나
- 플레이프레임워크
- 파이썬 데이터분석
- Adapter 패턴
- Hyperledger fabric gossip protocol
- akka 강좌
- 하이퍼레저 패브릭
- 엔터프라이즈 블록체인
- 하이브리드앱
- 블록체인
- Actor
- CORDA
- 파이썬 동시성
- 주키퍼
- Play2
- hyperledger fabric
- 이더리움
- Today
- Total
HAMA 블로그
파이썬 동시성 프로그래밍 - (9) 제네레이터 & 코루틴 & asyncio & async/await 본문
파이썬 동시성 프로그래밍 - (9) 제네레이터 & 코루틴 & asyncio & async/await
[하마] 이승현 (wowlsh93@gmail.com) 2017. 4. 30. 20:44연재순서
1. threading
2. Condition & Semaphore
3. Queue
4. multiprocessing
5. 비동기 (gevent)
6. 분산 (celery)
7. GPGPU (PyCUDA)
8. concurrent.future
9. 코루틴,asyncio,async/awit
제네레이터,코루틴,네이티브 코루틴과
ASYNC/AWAIT [번역]
참고 : 이 게시물은 주로 Python 3.4 에서 소개 된 기능에 대해 설명하며, 네이티브 코루틴과 async / await 구문은 Python 3.5에서 제공됩니다. 따라서 파이썬 3.5 이상을 사용하여 코드를 시험해 보는 것이 좋을 것 입니다.
제네레이터
제네레이터 함수는 어떤 값도 직접 반환하지 않고, 호출되면 반복자와 같은 제네레이터 객체를 건네줍니다. 그 후 제네레이터 객체에 대해 next ()를 호출하여 값을 반복 할 수 있습니다. 또는 for 루프를 실행하여 처리합니다.
그렇다면 제네레이터는 어떨때 유용할까요? 독자분의 상사가 최대 100 개의 숫자 시퀀스를 생성하는 함수를 작성하도록 요청했다고 가정 해 봅시다 ( range() 의 단순한 간략화 된 버전). 빈 리스트를 가져 와서 번호를 계속 추가 한 다음 번호가 있는 리스트을 반환하는 방식을 택했습니다. 그러나 요구 사항이 변경되고 최대 1억개의 숫자가 생성 되어야 하는것으로 변경 한다고 할 때. 이 번호를 리스트에 저장하면 곧 메모리가 부족해질 것입니다. 그런 상황에서 제네레이터가 활약하는데요. 즉 이 번호는 리스트에 모두 저장하지 않고 생성 할 수 있습니다. 다음과 같이 해봅시다.
굳이 메모리에 적재해두지 않고서도 원하는 만큼 번호를 출력 할 수 있으며, 위에서는 번호 9 이상을 출력하지 않습니다만, 함수 컨텍스트를 다시 시작하면 다시 시작됩니다.
요약 : 제네레이터 함수는 하나의 값을 반환하는 대신 실행을 일시 중지하고 여러 값을 생성 할 수있는 함수입니다. 또한 호출되면 iterable처럼 작동하는 제네레이터 객체를 제공하며 반복적으로 값을 얻을 수 있습니다.
코루틴
이제 제네레이터를 사용하여 함수 컨텍스트에서 데이터를 가져올 수 있고 실행을 일시 중지 할 수 있음을 알게 되었습니다. 근데 제네레이터에 데이터를 푸시하고 싶다면 어떻게 해야 할까요? 즉 제네레이터 자신이 계속 데이터를 만드는 것이 아니라, 외부에서 제공되는 데이터를 소비하는 역할을 하고 싶습니다. 이때 코루틴이 등장 할 때입니다. 값을 받는데 사용하는 yield 키워드는 함수 내부의 "=" 오른쪽에 있는 표현식으로 사용 할 수도 있습니다. 제네레이터 객체에 대해 send() 메서드를 사용하여 값을 함수로 다시 전달할 수 있는데요. 이를 "제네레이터 기반 코루틴" 이라고 합니다. 아래는 그 예입니다.
(역주: 함수와 제네레이터 , 코루틴 모두 def 를 통해 만듭니다. 이것에 대해 모두 다르게 표시해야 한다고 주장하는 사람들이 있으며, 파이썬의 창조자 귀도는 이에 반대하여 def 로 통일되어 있습니다. 그리고 코루틴은 반복이 목적이 아닙니다. 반복이 목적인 것은 분명히 제네레이터의 역할입니다. 코루틴은 외부와의 상호 작용입니다. )
소스를 살펴보시면 먼저 next () 함수를 사용하여 평소와 같이 값을 가져옵니다. 이것은 "Hello"를 얻습니다. 그런 다음 send () 메소드를 사용하여 값을 제네레이터에 보냅니다. 함수를 다시 시작하고 우리가 hello에 보낸 값을 할당하고 다음 줄로 이동하여 명령문을 실행합니다. 결국 우리는 send () 메소드의 반환 값으로 "World"를 얻습니다. 먼가 한바퀴 돈 느낌이네요.
우리가 제네레이터 기반 코루틴을 사용할 때 "제네레이터"와 "코루틴"이라는 용어는 일반적으로 같은 의미입니다. 그것들은 정확히 똑같은 것은 아니지만, 많은 경우에 종종 혼용됩니다. 그러나 Python 3.5에서는 네이티브 코루틴과 함께 async
/await
키워드가 주로 언급됩니다. 이 게시물의 후반부에서 논의 될 것 입니다.
파이썬 코루틴에 대한 개념은 요기 참고 -> Haerakai's Lab(파이썬의 코루틴)
Async I/O and the asyncio
module
(역주: 전체 시스템이 블러킹이 안되게 하는 방법으로 첫째, 멀티쓰레드를 통해 하나만 블럭되게 한다 2. 비동기 방식을 사용한다. 이렇게 2개로 크게 볼 수 있습니다. 네 맞습니다. asycnio 는 비동기 방식에 대한 이야기 입니다. 자바스크립트가 그러하듯이~)
yield from
를 사용했습니다. 그래서 우리는 그것에 임의의 초를 보내고 asyncio.ensure_future()를 사용하여 기본 이벤트 루프에서 코루틴의 실행을 스케쥴합니다. 그런 다음 루프가 계속 실행되도록 요청 합니다.for x in asyncio.sleep(random.randint(0, 5)): yield x
에 대한 멋진 syntactic sugar 입니다. 그것은 비동기 코드를 좀 더 간략히 만들어 주죠. Native Coroutines and async
/await
강조 표시된 선(노랑)을 살펴보십시오. def 키워드 앞에 async 키워드를 사용하여 네이티브 코루틴을 정의하고 있으며 네이티브 코루틴에서는 yield 대신 await 키워드를 사용합니다.
Native vs Generator Based Coroutines: Interoperability
구문의 차이점을 제외하고는 네이티브 와 제네레이터 기반 코루틴간에 기능상의 차이점은 없습니다. 구문을 혼용하는 것은 허용되지 않습니다. 그래서 제네레이터 기반 코루틴에서 await
혹은 네이티브 코루틴 내부에서 yield
/yield from
을 사용할 수 없습니다.
이런 차이점에도 불구하고 이들 간의 상호 운영이 가능합니다. 우리는 오래된 제네레이터 기반의 것들에
@ types.coroutine 데코레이터를 추가하기만 하면 되는데요. 그런 다음 다른 유형의 내부에서 사용할 수 있습니다. 네이티브 코루틴 (coroutine) 내부의 제네레이터 기반 코루틴을 통해await
할 수 있으며, 제네레이터 기반 코루틴안에서 네이티브 코루틴으로 부터 yield from
할 수 있습니다. 다음은 예입니다.
번역:
http://masnun.com/2015/11/13/python-generators-coroutines-native-coroutines-and-async-await.html
'Python' 카테고리의 다른 글
파이썬 Asyncio 를 이해하기 위한 여정 (2) | 2017.05.02 |
---|---|
파이썬과 동시성에 대한 정리 (0) | 2017.05.01 |
파이썬 동시성 프로그래밍 - (8) Concurrent.Futures & ProcessPoolExecutor (0) | 2017.04.27 |
파이썬 동시성 프로그래밍 - (7) GPGPU (pyCuda) (2) | 2017.04.27 |
파이썬 동시성 프로그래밍 - (6) 분산 (celery) (0) | 2017.04.27 |