Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 | 31 |
Tags
- Inductive Learning
- cross-entropy
- 대칭키
- Google Cloud
- zachary’s karate club
- 생성 모델
- PyTorch
- DeepLearing.AI
- Vertex AI
- session 미종료
- SSIM
- Spectral GNN
- ChatGPT
- public key
- 이상 탐지
- Transductive Learning
- posterior collapse
- 사회 네트워크 분석
- Spatial GNN
- prompt engineering
- PSNR
- 생성 모델 평가
- GNN
- deepseek
- mode collapse
- GCP
- Grad-CAM
- ARIMA
- kl divergence
- python3
Archives
- Today
- Total
데이터 과학 노트
Python async 정리: 사용법부터 스레드와의 차이까지 본문
Python async 완벽 정리: 사용법부터 스레드와의 차이까지
Python의 async/await는 비동기 프로그래밍(asynchronous programming)을 위한 문법이다.
하지만 많은 사람들이 오해하듯, 이것은 스레드(thread)로 구현된 구조가 아니다.async는 코루틴(coroutine) 기반으로, 단일 스레드 내에서 동시성(concurrency)을 구현한다.
1. async 기본 개념
async def: 비동기 함수를 정의할 때 사용한다.await: 비동기 함수 실행 중 일시 정지(양보) 후, 다른 코루틴이 실행되도록 한다.
이 두 키워드로 Python은 하나의 스레드에서 여러 작업을 비동기적으로 전환할 수 있다.
2. 기본 사용 예시
import asyncio
async def say_hello():
print("안녕!")
await asyncio.sleep(1) # 1초 대기 (비동기)
print("다시 안녕!")
async def main():
await say_hello()
asyncio.run(main())
출력:
안녕!
(1초 대기)
다시 안녕!await asyncio.sleep(1)은 프로그램 전체를 멈추지 않고,
다른 코루틴이 그 시간 동안 실행될 수 있도록 이벤트 루프에 제어를 넘긴다.
3. 여러 작업 동시에 실행하기
import asyncio
async def work(name, delay):
print(f"{name} 시작")
await asyncio.sleep(delay)
print(f"{name} 완료")
async def main():
await asyncio.gather(
work("A", 2),
work("B", 1),
work("C", 3),
)
asyncio.run(main())
출력 예시:
A 시작
B 시작
C 시작
B 완료
A 완료
C 완료asyncio.gather()를 사용하면 여러 비동기 작업을 동시에 실행할 수 있다.
실제로는 병렬이 아니라, 이벤트 루프가 번갈아가며 실행한다.
4. async와 스레드의 차이
| 구분 | asyncio (코루틴) |
threading (스레드) |
|---|---|---|
| 실행 방식 | 단일 스레드 내 협력적 실행 | 여러 스레드 병렬 실행 |
| 전환 방식 | await로 명시적 양보 |
OS가 자동 스케줄링 |
| 메모리 사용 | 가벼움 | 스레드마다 스택 필요 |
| I/O 효율 | 매우 높음 | 보통 |
| CPU 효율 | 낮음 (GIL 영향) | 조금 더 낫지만 여전히 GIL 영향 |
async는 논리적 동시성(concurrency)을 제공하지만,
물리적 병렬성(parallelism)은 제공하지 않는다.
5. CPU 연산 작업과 함께 사용하기
async는 I/O 중심의 작업에 최적화되어 있다.
CPU를 많이 사용하는 함수는 이벤트 루프를 막을 수 있으므로
스레드나 프로세스 풀을 함께 사용하는 것이 좋다.
import asyncio
from concurrent.futures import ThreadPoolExecutor
import time
def blocking_task():
time.sleep(2)
return "완료"
async def main():
loop = asyncio.get_running_loop()
result = await loop.run_in_executor(ThreadPoolExecutor(), blocking_task)
print(result)
asyncio.run(main())
이 코드는 블로킹 함수(time.sleep)를 별도 스레드에서 실행해
비동기 루프가 멈추지 않게 한다.
6. 결론
async는 스레드가 아닌 코루틴 기반의 비동기 구조다.- 이벤트 루프가 여러 작업을 번갈아 실행한다.
- I/O 중심 작업에 매우 효율적이다.
- CPU 중심 작업에는 스레드나 프로세스 풀을 병행하는 것이 좋다.
7. 요약
async def로 코루틴 정의await로 비동기 작업 일시 정지asyncio.gather()로 여러 작업 동시 실행- 스레드가 아니라 이벤트 루프 기반
- CPU 연산은
run_in_executor()로 분리 실행
'Development' 카테고리의 다른 글
| tmux (terminal multiplexer) (1) | 2024.03.27 |
|---|