행복한 하루
[MicroPython] async 함수에서 return(result) 값 받는 방법 본문
안녕하세요.
asyncio는 async/await 구문을 사용하여 동시성 코드를 작성할 수 있게 해주는 모듈로, asyncio를 사용하면 단일 스레드 작업을 병렬로 처리할 수 있습니다.
그리고 async 함수에서 리턴하는 값도 받을 수 있습니다. 그런데 MicroPython에서는 리턴 값을 받는 방법이 약간 달라서 남겨봅니다.
- Python3.7 이전과 이후에 따라 ansyncio모듈에 추가된 함수가 있어 사용방법 차이가 있는 것으로 보입니다. 현재 MicroPython1.20, python3.9으로 테스트했습니다.
1. 일반 Python에서 비동기 함수에서 리턴 받는 코드
- 간단한 샘플 코드로 숫자의 합을 구하는 비동기 함수를 만들고 A, B의 두 개의 Task로 해서 coroutine으로 생성합니다.
- sum() 함수에서 total 값을 반환(return)하면 호출한 함수 쪽에서 받을 수 있습니다.
- 특별한 문제없이 A, B의 총합을 확인할 수 있습니다.
import asyncio
import time
async def sum(name, numbers):
start = time.time()
total = 0
for number in numbers:
#await asyncio.sleep(1)
await sleep()
total += number
print(f'작업중={name}, number={number}, total={total}')
end = time.time()
print(f'작업명={name}, 걸린시간={end-start}')
return total
async def main():
start = time.time()
task1 = asyncio.create_task(sum("A : ", [1, 2, 3, 4]))
task2 = asyncio.create_task(sum("B : ", [1, 2, 3, 4, 5]))
await task1
await task2
result1 = task1.result()
result2 = task2.result()
mainEnd = time.time()
print(f'A 총합={result1}, B 총합={result2}')
print(f'총 걸린시간={mainEnd-start}')
print("FINISH")
if __name__ == "__main__":
asyncio.run(main())
2. MicroPython에서 비동기 함수에서 리턴 받는 코드
- import uasyncio as asyncio로 import 부분을 바꾸고 위의 동일한 코드를 MicroPython에서 실행하면 에러가 발생합니다. 어려운 기능도 아닌 것 같은데, 당연히 있어야 하는 함수가 아닐까 했는데, 속성이 없다고 에러가 납니다.
- MicroPython 사이트에 한 분이 질문 겸 답변을 올려 알게 되었습니다. 문서에도 나오지 않는다고 ^^
- result() 함수는 없지만, 함수가 완료되면 .data 속성에 저장되는 것으로 보입니다.
- 아래와 같이 result1,2 위치를 await 쪽으로 바꿔 주면 리턴되는 값을 확인할 수 있습니다. 그래서 일반 Python에서 결과와 동일한 것을 확인할 수 있습니다.
import uasyncio as asyncio
import time
async def sum(name, numbers):
start = time.time()
total = 0
for number in numbers:
#await asyncio.sleep(1)
await sleep()
total += number
print(f'작업중={name}, number={number}, total={total}')
end = time.time()
print(f'작업명={name}, 걸린시간={end-start}')
return total
async def main():
start = time.time()
task1 = asyncio.create_task(sum("A : ", [1, 2, 3, 4]))
task2 = asyncio.create_task(sum("B : ", [1, 2, 3, 4, 5]))
result1 = await task1
result2 = await task2
mainEnd = time.time()
print(f'A 총합={result1}, B 총합={result2}')
print(f'총 걸린시간={mainEnd-start}')
print("FINISH")
if __name__ == "__main__":
asyncio.run(main())
감사합니다.
<참고 사이트>
1. Get task result from an asyncio Task object?
https://forum.micropython.org/viewtopic.php?t=11943&p=64943
2. [Python] 비동기 프로그래밍 동작 원리 (asyncio)
https://it-eldorado.tistory.com/159
3. 071 비동기 방식으로 프로그래밍하려면? ― asyncio
'Programming > Python' 카테고리의 다른 글
[Python] 정수를 16진수(HEX)로 몇 가지 출력(표현)하는 방법 (0) | 2023.06.22 |
---|