Programming/Python

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

변화의 물결1 2024. 7. 19. 00:06

 

 

안녕하세요.

 

 asyncio는 async/await 구문을 사용하여 동시성 코드를 작성할 수 있게 해주는 모듈로, asyncio를 사용하면 단일 스레드 작업을 병렬로 처리할 수 있습니다.

  

 그리고 async 함수에서 리턴하는 값도 받을 수 있습니다.   그런데 MicroPython에서는 리턴 값을 받는 방법이 약간 달라서 남겨봅니다.

  

   asyncio는 async/await 구문을 사용하여 동시성 코드를 작성할 수 있게 해주는 모듈로, asyncio를 사용하면 단일 스레드 작업을 병렬로 처리할 수 있습니다.


 

 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    

 

 

반응형