반응형
asyncio 를 이용한 파이썬 비동기 코드
파이썬도 javascript ECMAScript2017 에서 쓰이는 async, await 사용으로 비동기 코딩이 가능하다!
비동기 함수 앞에 async 를 붙여주면되고, 해당 함수의 실행결과를 기다려야 할때 await 를 붙여주면 끝!
비동기 함수를 실행할때는 asyncio.run 을 이용하면 된다.
import asyncio
async def greetings():
print("Welcome")
await asyncio.sleep(1)
print("Good by")
async def main():
await greetings()
await greetings()
asyncio.run(main())
하지만 이렇게 하면 동기 프로그램 하고 똑같이 순차적으로 실행된다 =ㅅ=;
동시 실행을 위해서 asyncio.create_task 를 이용한다.
import asyncio
import time
async def say_something(delay, words):
print(f"Before: {words} {delay}")
await asyncio.sleep(delay)
print(f"After: {words} {delay}")
async def main():
print(f"start: {time.strftime('%X')}")
task1 = asyncio.create_task(say_something(1, "First task started."))
task2 = asyncio.create_task(say_something(2, "Second task started."))
await task1
await task2
print(f"Finished: {time.strftime('%X')}")
asyncio.run(main())
간단하게 동시 프로그램이 가능하게 되었다!!
근데 호출 함수가 많으면 await 를 계속 붙여서 리스트로 활용해야 하나?
아니다. 이를 위해 함수가 있다!. 또한 ajax 같이 호출 후, 리턴값을 받기 위해서도 해당 함수를 사용할 수 있다.
그건 바로 asyncio.as_completed, asyncio.gather 두개다.
각각의 차이점은 하나씩 돌려주냐, 전체 다 돌려주냐 의 차이다. 소스로 확인!
import asyncio
async def say_something(delay, words):
print(f"Before: {words} {delay}")
await asyncio.sleep(delay)
return f"After: {words} {delay}"
async def main():
task1 = asyncio.create_task(say_something(1, "First task started."))
task2 = asyncio.create_task(say_something(2, "Second task started."))
# as_completed
for res in asyncio.as_completed((task1, task2)):
compl = await res
print(f"completed: {res} => {compl}")
task1 = asyncio.create_task(say_something(1, "First task started."))
task2 = asyncio.create_task(say_something(2, "Second task started."))
# gathered
compl = await asyncio.gather(task1, task2)
print(f"completed: {res} => {compl}")
asyncio.run(main())
as_completed 를 쓸때 하나의 튜플 (task1, task2) 로 주는것에 유의 하면 된다.
반응형