generator coroutine 사용
import types
# generator base coroutine을 사용한 비동기 로직 yield로 제어권을 서로 계속 넘겨준다.
@types.coroutine
def switch():
yield
async def coro1():
print('C1: Start')
await switch()
print('C1: a')
await switch()
print('C1: end')
async def coro2():
print('C2: Start')
await switch()
print('C2: a')
await switch()
print('C2: end')
def run(cors):
while cors:
print("코루틴이 다시 시작할 지점을 기억하고 있다.")
for corou in [c1,c2]:
corou.send(None)
c1 = coro1()
c2 = coro2()
task = [c1, c2]
run(task)
asyncio 사용
import asyncio
async def co1():
print('코루틴 1 실행')
await asyncio.sleep(5)
print('코루틴 1 재개')
return '코루틴 1 종료'
async def co2():
print('코루틴 2 실행')
await asyncio.sleep(2)
print('코루틴 2 재개')
return '코루틴 2 종료'
async def main():
tasks = [co1(), co2()]
result = await asyncio.gather(*tasks)
print(result)
#tasks = [co1(), co2()]
#for res in await asyncio.gather(*tasks):
# print(f'서브 스레드 종료 {res}')
#co1_r = await co1() 기다림1
#co2_r = await co2() 기다림1 끝나고 다시 기다림2
#print(co1_r, co2_r)
#loop = asyncio.get_event_loop() # 코루틴 실행과정을 위한 무한루프
#co1_r = loop.create_task(co1()) # 기다리지 않고 실행
#co2_r = loop.create_task(co2()) # 기다리지 않고 실행 됐기 때문에 메인 스레드가 종료되서 코루틴 1 실행, 코루틴 2 실행만 출력됨
asyncio.run(main())
*concurrent.futures(다중 스레드, 비동기/Non-block 방식)
executor.submit(함수, 매개변수) -> 별도의 스레드로 실행중인 future 객체를 얻음 (메인 스레드는 동작중)
future.result() -> 결과를 얻음 (아직 실행중이라면 메인 스레드가 결과를 받을때 까지 중지할 수 있다)
futures.as_completed() -> 완료되거나 이셉션이 발생한 future들을 순차적으로 받을 수 있다(대게 포문)
*asyncio(단일 스레드, 비동기/Non-block 방식)
이러한 대기시간 동안에 해당 작업 외에 다른 작업으로의 전환을 단일 스레드에서 처리할 수 있는 기반 기술들은 파이썬의 코루틴이다.
I/O 처리를 기다리는 역할을 코루틴에게 위임하고, 그 시간 동안 다른 코루틴을 이용해서 별도의 작업을 또 비동기로 처리할 수 있다.
task -> asyncio.future의 자식 클래스이며 concurrent.future.Future와 거의 같은 API를 제공 / 코루틴을 감싼 객체
await -> 서브 코루틴에 제어권을 주는것 await 없이 함수를 호출하면 호출은 했지만 제어권이 없어 런타임 오류발생
-> 메인 함수에서 await를 추가해서 호출하거나 asyncio.create_task()로 이벤트 루프에 코루틴 객체를 전달하여 실행을 등록
asyncio.get_event_loop() -> 루틴을 모아놓을 빈 리스트 [] 생성
-> send()를 반복적으로 끊임없이 호출하여 멈춰있는 코루틴을 실행시키는 역할
asyncio.create_task() -> 실행시킬 코루틴을 리스트에 등록(예약) schedule, 이벤트 루프에 등록과 같음
loop.run_until_complete() -> 코루틴 실행(단일)
loop.run_in_executor(pool, func) -> blocking 함수를 awaitable하게 돌릴 수 있도록 task로 만들어주는 함수
-> 기본 executor 또는 thread,process executor에서 할지 pool을 넣어서 지정해줄 수 있다
asyncio.gather(*aws) -> 비동기로 두 개 이상의 코루틴을 등록할 때 사용, unpacked 형태로 넣어주어야 한다.
파이썬 3.7 이상은 asyncio.run() 이걸로 이벤트 루프를 만들고 코루틴을 실행할 수 있음 (루프 생성을 안해줘도 된다는 뜻)
이벤트 루프가 태스크들을 여러개 가지고 있고 한번에 한 태스크들씩 실행하는데
태스크에 감싸진 코루틴이 퓨처 객체(실행흐름)가 값을 리턴해 줄 때까지 대기중이라면
이벤트 루프는 다른 태스크를 실행시키거나 I/O작업을 수행한다.
https://it-eldorado.tistory.com/159
해당 댓글은 삭제되었습니다.