행복한 하루

[MicroPython] async 함수에서 return(result) 값 받는 방법 본문

Programming/Python

[MicroPython] async 함수에서 return(result) 값 받는 방법

변화의 물결 2023. 5. 24. 11:36

 

안녕하세요.

 

   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

https://wikidocs.net/125092  

 

 

Comments