728x90
반응형
개요
프로그래밍에서 동시성(Concurrency)과 병렬성(Parrallelism)은 시스템의 효율성과 성능을 높이는 데 필수적인 개념입니다. 두 용어는 종종 혼용되지만, 실제로는 근본적인 차이가 있습니다.
주제 개념 및 용어 정리
구분 | 동시성(Concurrency) | 병렬성(Parallelism) |
실제 단어 뜻 | 동시 + 성 : 여러 일이 함께 진행될 수 있는 성질 | 병렬 + 성 : 여러 일이 실제로 나란히 수행되는 성질 |
IT 용어 개념 | 단일 코어에서도 여러 작업을 동시에 진행되는 것처럼 보이게 처리하는 논리적인 기술(시간을 짧게 쪼개 번갈아 가며 작업) | 멀티 코어 환경에서 여러 작업을 진짜로 동시에 실행하는 물리적 기술(하드웨어적 다중 처리) |
핵심 | 관리(Dealing) : 여러 작업을 동시에 처리하는 방법을 구조화하고 관리하는 것에 중점 | 실행(Doing) : 여러 작업을 말 그대로 동시에 수행하는 것에 중점 |
사용 사례 및 예시
이해를 돕기 위한 실행활 예시
- 동시성 : 바리스타 한 명이 여러 손님(작업)의 주문을 받으면서(Task1), 커피를 내리다가(Task2), 다음 손님의 컵을 준비하는(Task3) 등 빠르게 작업을 전환하며 여러 주문을 진행중 상태로 관리하는 것. 실제로는 한 순간에 하나의ㅏ 작업만 하고 있지만, 사용자는 동시에 처리되는 것처럼 보입니다.
- 병렬성 : 두명 이상의 바리스타가 동시에 각각의 커피 머신(CPU 코어)를 이용해 서로 다른 손님의 커피를 동시에 내리는 것. 작업들이 독립된 자원에서 동시에 처리됩니다.
실제 작동 원리 및 IT 예시
구분 | 동시성(Concurrency) | 병렬성(Parallelism) |
작동 원리 | Context Switching(문맥 교확) : CPU가 한 직업에 할당된 시간을 매우 짧게 나누어(Time Slice), 여러 스레드나 프로세스 사이를 빠르게 전환하며 실행 | 멀티 코어 활용 : 각기 다른 CPU 코어가 독립적으로 서로 다른 작업을 할당 받아 동시에 처리 |
주요 활용 기술 | 멀티 스레딩(Single-Core에서), 비동기 프로그래밍(Async/Await, Coroutines) 등 | 멀티프로세싱, 스레드 풀(Multi-Core에서) |
대표적인 사용처 | I/O 집중 작업(I/O-Bound): 웹 서버에서 여러 클라이언트의 요청을 대기 시간 없이 동시에 처리, 파일 다운로드, 사용자 인터페이스(UI) 이벤트 처리.(대부분의 시간을 I/O 대기에서 보내는 작업 | CPU 집중 작업(CPU-Bound) : 대규모 데이터 분석, 복잡한 과학 계산, 3D 그래픽 렌더링, 고해상도 비디오 인코딩.(대부분의 시간을 게산에 사용하는 작업) |
왜 사용하고, 언제 필요한가?
왜 사용하는지?(목적)
- 동시성 : 응답성(Responsiveness)과 효율성을 높이기 위해 사용합니다. 작업이 I/O 대기 상태일 때 CPU가 놀지 않고 다른 유효한 작업을 수행하도록 하여 시스템 자원(CPU)의 활용을 극대화하고 사용자에게 빠른 응답을 제공합니다.
- 병렬성 : 처리량(Throughput)과 연산 속도를 높이기 위해 사용합니다. 하나의 작업을 여러개의 독립적인 작업으로 나누어 여러 코어에서 동시에 처리함으로써 전체 작업 완료 시간을 단축시킵니다.
왜 필요한지?
현대의 애플리케이션은 동시에 많은 작업을 처리해야합니다.
- I/O 대기 문제 해결 : 웹 요청, 데이터베이스 접근 등 대기 시간이 긴 작업이 하나의 실행 흐름을 멈추게 하는 것을 방지하여 시스템의 멈춤 현상을 없앱니다.(동시성)
- 성능 극대화 : 멀티 코어 CPU를 효율적으로 사용하여 하드웨어의 성능 잠재력을 최대로 끌어냅니다.(병렬성)
언제 사용하는지?
- 동시성 : 주로 대기 시간(Latency)이 길거나 여러 요청을 효율적으로 관리해야하는 웹 서버, 네트워크 통신, GUI 애플리케이션 등에 사용됩니.
- 병렬성 : 주로 방대한 계산량이 필요한 데이터 마이닝, 머신러닝 모델 학습, 복잡한 물리 시뮬레이션 등 CPU의 연산력이 집중적으로 필요한 분야에 사용됩니다.
1. 동시성 구현 방법 : 멀티 스레딩과 비동기 프로그래밍
멀티스레딩(Multi-threading) : 하나의ㅏ 프로세스 내에서 여러 개의 실행 흐름(스레드)을 생성하여 CPU 시간을 공유하게 합니다.
- 장점 : 스레드 간 자원 공유가 용이하여 데이터 교환이 빠릅니다.
- 단점 : 공유 자원에 동시에 접근할 때 경쟁 조건(Race Condition)이 발생하기 쉬워 동기화(Synchronization) 메커니즘(Lock, Mutex 등)이 필수적이며, 이로 인해 복잡성이 증가합니다.
비동기 프로그래밍(Asynchronous Programming) : 작업의 시작을 알리고 결과가 준비될 때까지 기다리지 않고(Non-blocking), 다른 작업을 진행하다가 결과가 나오면 콜백 함수 등을 통해 처리하는 방식입니다.
- 장점 : 단일 스레드에서도 I/O 작업을 효율적으로 처리하여 동시성을 확보합니다. 자원 공유 문제가 적습니다.
- 단점 : 코드의 흐름이 복잡해질 수 있고, 디버깅이 어려울 수 있습니다.
2. 병렬성 구현 방법 : 멀티 프로세싱
멀티 프로세싱(Multi-processing) : 여러 개의 독립적인 프로세스를 생성하여 각 프로세스가 서로 다른 CPU 코어에서 실행되게 합니다.
- 장점 : 각 프로세스는 독립적인 메모리 공간을 가지므로 공유 자원 문제가 비교적 덜 발생하며, 안정성이 높습니다.
- 단점 : 프로세스 생성 및 전환 비용이 크고, 프로세스 간 데이터 통신(IPC)에 추가적인 오버헤드가 발생합니다.
예시 코드
동시성(멀티 스레딩 - I/O 대기 시 다른 작업 전환)
import threading
import time
def task_io(name):
print(f"[{name}] I/O 작업 시작 (대기)")
time.sleep(2) # I/O 대기 시간 가정
print(f"[{name}] I/O 작업 완료")
# 싱글 코어에서 두 작업을 동시에 '진행 중'으로 관리
t1 = threading.Thread(target=task_io, args=("스레드-A",))
t2 = threading.Thread(target=task_io, args=("스레드-B",))
t1.start()
t2.start()
# 결과: 두 작업이 거의 동시에 시작하여 번갈아 진행되는 것처럼 보임
병렬성(멀티프로세싱 - CPU 연산 동시 실행)
import multiprocessing
import math
def task_cpu(n):
result = sum(math.sqrt(i) for i in range(n)) # CPU 집약적 계산
print(f"[프로세스] 계산 완료: {result}")
N = 10**6
# 멀티 코어에서 각 프로세스가 독립적인 코어에서 실행
p1 = multiprocessing.Process(target=task_cpu, args=(N,))
p2 = multiprocessing.Process(target=task_cpu, args=(N,))
p1.start()
p2.start()
# 결과: 두 작업이 실제로 동시에 실행되어 총 시간이 단축됨
장단점 및 특징
구분 | 장점 | 단점 | 특징 |
동시성 | 시스템 응답성 향상, 단일 코어에서 자원 활용 극대화, I/O 바운드 작업에 효율적 | Context Switching 오버헤드 발생, 공유 자원 접근 시 동기화 문제(데드락, 경쟁 조건) 발생 가능 | 논리적 개념, 함께 진행되는 것처럼 보임 |
병렬성 | 처리량(Throughput) 및 연산 속도 대폭 향상, CPU 바운드 작업에 최적, 프로세스 격리로 안정성 높음 | 멀티 코어 하드웨어 필수, 프로세스 생성 및 통신 비용(오버헤드)이 큼 | 물리적 개념, 진짜로 동시에 실행됨 |
결론
동시성을 여러 작업을 효율적으로 관리하여 시스템의 응답성을 개선하는 소프트웨어적 접근이고, 병렬성은 여러 작업을 동시에 실행하여 연산 속도를 높이는 하드웨어적 접근입니다.
현대 시스템에서는 동시성과 병렬성이 상호 보완적으로 사용됩니다. 예를 들어 멀티 코어(병렬성) 환경에서 멀티스레딩(동시성)을 구현하면, 여러 작업을 동시에 처리하는 것 처럼 보이면서 실제로도 여러 코어에서 동시에 실행되어 최고의 성능을 끌어낼 수 있습니다.
반응형
'Dev > Python' 카테고리의 다른 글
[Python] 이벤트 루프 (Event Loop): 비동기 작업들의 실행 순서를 관리하고 제어하는 핵심 엔진 (0) | 2025.10.11 |
---|---|
[Python] 튜플(Tuple) & 딕셔너리(Dictionary) (0) | 2025.10.04 |
[Python] 빛과 그림자 : GIL(Global Interpreter Lock) 파헤치기 (0) | 2025.10.03 |
[Python] 파이썬 이터레이터와 제너레이터: 메모리를 잡아먹는 괴물 리스트 대신 현명하게 데이터 다루기 (0) | 2025.09.27 |
[Python] Python 예외 처리 (0) | 2025.09.26 |