로그인회원가입

MicroPython 멀티태스킹: 비동기(asyncio)와 멀티스레드, 언제 뭘 써야 할까?

** 비동기와 멀티 스레드 차이

🥊 한눈에 보는 핵심 차이점

구분비동기 (uasyncio)멀티스레드 (_thread)
작업 방식협력적 (Cooperative)
내가 await으로 쉴 때 다른 일 함
선점형 (Preemptive)
OS/CPU가 강제로 작업 전환함
메모리(RAM) 사용매우 적음 (메모리 절약)많이 듦 (스택 메모리 각각 할당)
자원 공유/충돌안전함 (내가 쉴 때만 전환되므로)위험함 (변수/하드웨어 동시 접근 충돌)
동시 작업 수수십~수백 개 가능보드에 따라 보통 2개(코어 수 제한)

💡 주요 차이점 상세 설명

1. 작업 switching(전환) 제어권: 내가 넘기느냐 vs 강제로 빼앗기느냐

  • 비동기 (uasyncio):
    • 작업이 진행되다가 await을 만나는 순간 “나 지금 대기 중이니까 다른 일 해~” 하고 스스로 제어권을 넘깁니다.
    • 코드 예측이 쉽고, 내가 원하는 순간에만 작업 전환이 일어나므로 데이터가 꼬일 일이 적습니다.
  • 멀티스레드 (_thread):
    • CPU가 일정 시간(몇 밀리초)마다 코드를 실행 중인 중간에 강제로 멈추고 다른 스레드로 넘겨버립니다.
    • 만약 스레드 A가 센서 값을 읽어서 전역 변수에 쓰는 중에, 스레드 B가 그 변수를 읽으려고 접근하면 데이터가 깨지거나 보드가 다운(Crash)될 수 있습니다. (이를 막으려면 Lock, Mutex 같은 복잡한 장치가 필요함)

2. 메모리(RAM) 소비량 (마이크로파이썬에서 가장 중요한 이유!)

마이크로컨트롤러는 PC와 달리 RAM이 수백 KB 정도로 매우 적습니다.

  • 멀티스레드:
    • 스레드를 하나 생성할 때마다 독립적인 메모리 공간(Stack)을 최소 수 KB씩 크게 떼어서 할당해줘야 합니다.
    • 스레드를 3~4개만 띄워도 메모리 부족(MemoryError)이 발생하기 쉽습니다.
  • 비동기:
    • 하나의 스레드(Single Thread) 안에서 “스케줄표”만 가지고 번갈아 돌기 때문에 메모리를 거의 먹지 않습니다. 수십 개의 비동기 루틴을 돌려도 메모리가 여유롭습니다.

3. 멀티코어 활용 유무

  • 멀티스레드:
    • ESP32나 RP2040 같은 듀얼코어 보드에서 진짜 물리적인 2개의 코어를 동시에 각각 돌리고 싶을 때 유용합니다. (예: 코어 0은 모터 제어, 코어 1은 화면 출력)
  • 비동기:
    • 기본적으로 1개의 코어 안에서 효율적으로 시간을 쪼개 쓰는 방식입니다.

🎯 결론: 언제 뭘 써야 할까?

✅ 이럴 땐 uasyncio (비동기)를 쓰세요!

  • 센서 값 주기적 읽기, LED 깜빡이기, 버튼 입력을 받으면서 네트워크(Wi-Fi/Web) 통신 처리하기 등 “대기 시간(Delay/Sleep/네트워크 응답)”이 많은 대부분의 IoT 작업
  • 메모리가 아슬아슬하거나 여러 개의 단순 루틴을 동시에 돌려야 할 때

✅ 이럴 땐 _thread (멀티스레드)를 쓰세요!

  • 지연 시간 없이 CPU를 100% 써서 연산만 주구장창 하는 두 작업을 물리적으로 분리하고 싶을 때
  • 타임 크리티컬해서 한쪽 코어가 멈추지 않고 오직 하드웨어/모터 제어만 전담해야 할 때 (예: 듀얼 코어의 코어 1개를 전용 엔진으로 쓸 때)

한 줄 요약:

간단한 대기 작업이 많다면 **메모리가 적게 들고 안전한 uasyncio**가 정석이고, 물리적 듀얼코어를 써서 하드웨어를 극한으로 굴려야 할 때만 제한적으로 **_thread**를 씁니다.

코멘트

답글 남기기