Coroutine

choonghee-lee·2020년 7월 27일
0

WeCode

목록 보기
14/20

Assignment

1

넘나 쉬운것 ..?

import time

def coroutine_test():
    greeting = "good "
    while True:
        text = (yield greeting)
        greeting = "good "    # 바뀐 부분
        print("text = ",end=""), print(text)
        greeting += text


if __name__ == "__main__":
    cr = coroutine_test()
    print("cr=",end=""), print(cr)

    next(cr)
    time.sleep(2)

    print("send 1")
    print(cr.send("morning"))
    time.sleep(2)

    print("send 2")
    print(cr.send("afternoon"))
    time.sleep(2)

    print("send 3") 
    print(cr.send("evening"))
    time.sleep(2)

결과

cr=<generator object coroutine_test at 0x10e9347b0>
send 1
text = morning
good morning
send 2
text = afternoon
good afternoon
send 3
text = evening
good evening

2

두번째 코드를 asynciocoroutine을 활용하여 수정해보기가 두 번째 과제다. 주석에 코드 설명을 놓았다.

import asyncio

"""
코루틴은 반복의 목적이 아니라고 한다.
하지만 나는 반복해서 썼다 .. ㅋㅋ
"""
async def coroutine(num=50000000):
    result_value = 0
    while result_value < num:
        result_value += 1
    return result_value

async def main():
    """
    코루틴은 "awaitable"한 객체이므로 사용가능하다
    await 뒤에 코루틴 객체를 지정하면 해당 객체가 끝날 때까지 기다린 뒤 결과를 반환한다.
    async 키워드를 사용하는 네이티브 코루틴만 사용 가능하다.
    """
    one = await coroutine()
    two = await coroutine()
    print("ret_value =",end="")
    print(one+two)
    print("end of main")
    
if __name__ == "__main__":
    """
    이벤트 루프는 asyncio의 핵심이다.
    이벤트 루프는 비동기 태스크 및 콜백을 실행하고
    네트워크 IO를 수행하며 자식 프로세스를 실행한다.
    """
    loop = asyncio.get_event_loop()
    """
    코루틴이 완료할 때 까지 실행한다.
    """
    loop.run_until_complete(main())
    """
    이벤트 루프를 닫는다.
    이 함수를 호출할 때 루프는 반드시 실행 중이지 않아야 한다.
    모든 큐를 비우고 실행기를 종료하지만, 완료할 때까지 기다리지 않는다.
    """
    loop.close()

실행결과는 다음과 같다.

--- 5.712172031402588 seconds ---
ret_value =100000000
end of main

3

세번째 과제는 이번 섹션에서 coroutine 을 학습하면서 배운것을 정리해서 블로깅하는 과제이다.

앞서 공부한 프로세스와 스레드는 하나의 변수에 값을 동시에 쓰거나 읽을 때 동기화 문제가 발생해서 여러가지 기법을 동원해서 해결해야 했다. 하지만 코루틴은 이런 기법을 적용하지 않고도 원하는 작업을 할 수 있다.

코루틴이란?

코루틴 (coroutine)은 cooperative routine을 의미하는데 서로 협력하는 루틴이라는 뜻이다. 즉, 메인 루틴과 서비 루틴처럼 종속된 관계가 아니라 서로 대등한 관계이며 특정 시점에 상대방의 코드를 실행한다. 아래는 파이썬 코딩도장에서 가져온 코루틴의 동작 과정이다.

코루틴은 함수가 종료되지 않은 시점에서 메인 루틴의 코드를 실행하고 다시 돌아와서 코루틴의 코드를 실행할 수 있다.

코루틴의 경우에는 루틴을 진행하는 특정 위치에 멈출 수 있고 필요할 때 다시 나머지 루틴을 수행할 수 있다. 그리고 코루틴은 진입점이 여러개이기 때문에 메인루틴에 종속적이지 않아 대등하게 주고 받을 수 있는 특징이 있다.

파이썬의 코루틴에는 다음과 같은 특징이 있다.

  1. yield 문이라는 특수한 구문이 있다. return 처럼 동작하지만, 사실 입력으로 동작한다.
  2. next(coroutine)은 코루틴 함수의 첫번째 yield까지 호출하고 대기한다. 다음 next()를 호출하면 다음 yield 까지 실행한다. 더 이상 yield가 없는데 next를 호출하면 StopIteration이 발생한다.
  3. 만약 yield가 특정 변수에 할당되면, coroutine.send(value)를 호출해 주어야한다. 즉, yield를 통해서 메인루틴과 서브루틴간의 값을 이동시키면서 원하는 로직을 수행하면된다.
profile
뭐든지 열심히하는 타입 😎

0개의 댓글