개발/Python

[고급반] Step 3. Concurrency & Parallel: 멀티태스킹의 두 얼굴 완벽 이해하기

ophelisis 2026. 1. 5. 14:18
반응형

현대 소프트웨어 개발에서 "빠른 서비스"는 필수입니다. 하지만 무작정 스레드를 늘린다고 속도가 빨라지지는 않습니다. 내 프로그램이 왜 느린지, 어떤 방식의 병렬 처리가 필요한지 명확한 개념부터 실전 적용법까지 알아봅니다.

1. ❓ [Concurrency vs Parallel] 개념의 실체

많은 개발자가 이 둘을 혼용하지만, 핵심은 '동시'의 의미가 물리적인가 논리적인가에 있습니다.

  • 동시성 (Concurrency): 여러 작업을 번갈아 가며 처리하여 동시에 실행되는 것처럼 보이게 하는 논리적인 개념입니다. (싱글 코어에서도 가능)
  • 병렬성 (Parallelism): 여러 작업을 실제로 동시에 물리적인 여러 코어에서 처리하는 개념입니다. (멀티 코어 필수)

"동시성은 한 번에 많은 것을 다루는(Dealing) 것이고, 병렬성은 한 번에 많은 것을 하는(Doing) 것이다." - Rob Pike


2. 🔍 주요 원인 분석 (체크리스트)

프로그램의 성능이 개선되지 않거나 예상치 못한 버그가 발생한다면 아래 사항을 체크해 보세요.

  • 작업 성격 파악: 내 작업이 I/O Bound(네트워크, 파일 읽기)인가, 아니면 CPU Bound(복잡한 계산)인가?
  • Python GIL 확인: 파이썬 환경이라면 GIL(Global Interpreter Lock) 때문에 멀티 스레딩이 병렬로 작동하지 않는다는 것을 인지하고 있는가?
  • Race Condition: 여러 스레드가 동일한 자원에 동시에 접근하여 데이터 정합성이 깨지고 있지 않은가?
  • Context Switching 비용: 너무 많은 스레드/프로세스를 생성하여 오버헤드가 실제 작업 시간보다 길어지고 있지 않은가?

3. 🛠️ 실전! 해결 방법

💻 I/O Bound 작업 (Threading / Asyncio)

웹 크롤링이나 API 호출처럼 '기다리는 시간'이 많은 작업은 동시성(Concurrency) 모델이 적합합니다.

Python
 
import asyncio
import aiohttp

async def fetch_url(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            return await response.text()

# 비동기 방식으로 여러 요청을 동시에 처리 (Concurrency)
async def main():
    urls = ["https://google.com", "https://naver.com", "https://github.com"]
    tasks = [fetch_url(url) for url in urls]
    results = await asyncio.gather(*tasks)
    print(f"{len(results)}개의 페이지 수집 완료")

asyncio.run(main())

💻 CPU Bound 작업 (Multiprocessing)

데이터 분석이나 이미지 처리처럼 연산이 많은 작업은 병렬성(Parallelism)을 위해 프로세스를 분리해야 합니다.

Python
 
from multiprocessing import Pool

def complex_calculation(n):
    # CPU를 많이 사용하는 작업
    return sum(i * i for i in range(n))

if __name__ == "__main__":
    numbers = [10**7, 10**7 + 1, 10**7 + 2, 10**7 + 3]
    
    # 멀티 코어를 활용하여 실제 병렬 처리 (Parallelism)
    with Pool(processes=4) as pool:
        results = pool.map(complex_calculation, numbers)
    print(f"결과 값: {results}")

4. 💡 시니어의 조언: "인사이트 한 줄"

"병렬 처리는 공짜가 아닙니다. 설계되지 않은 병렬화는 버그를 병렬로 생성할 뿐입니다. 항상 데이터 공유를 최소화하는 구조를 먼저 고민하세요."

반응형