동시성과 병렬성의 차이
동시성(Concurrency)은 여러 작업을 번갈아 처리하는 것이고, 병렬성(Parallelism)은 여러 작업을 동시에 처리하는 것입니다. 40년간 멀티스레딩을 다뤄온 저로서는 이 구분이 매우 중요하다고 강조합니다. 싱글 코어에서도 동시성은 가능하지만, 병렬성은 멀티코어가 필요합니다. 비동기 I/O는 동시성, CPU 집약 작업 분산은 병렬성입니다.
스레드와 프로세스
프로세스는 독립된 메모리 공간을 가진 실행 단위입니다. 스레드는 프로세스 내에서 메모리를 공유하는 실행 흐름입니다. 스레드 간 통신은 빠르지만 동기화가 필요합니다. 프로세스 간 통신(IPC)은 안전하지만 오버헤드가 있습니다. 파이썬의 GIL처럼 언어마다 스레드 모델이 다릅니다.
동기화와 락
공유 자원에 여러 스레드가 접근하면 Race Condition이 발생합니다. 뮤텍스(Mutex), 세마포어로 상호 배제를 구현합니다. 하지만 락을 잘못 사용하면 데드락(교착 상태)이 발생합니다. 락을 오래 잡으면 성능이 저하됩니다. Lock-free 자료구조는 락 없이 동시성을 달성합니다.
현대적 동시성 모델
액터 모델(Erlang, Akka): 메시지 전달로 통신, 공유 상태 없음. CSP(Go, Clojure): 채널을 통한 통신. async/await(JavaScript, Python, Rust): 코루틴 기반 비동기. 작업 훔치기(Work Stealing): 효율적인 작업 분배. 각 모델의 장단점을 이해하고 상황에 맞게 선택합니다.
병렬 프로그래밍 팁
가능하면 공유 상태를 피합니다. 불변 데이터를 사용합니다. 락 범위를 최소화합니다. 고수준 추상화(병렬 컬렉션, 스레드 풀)를 사용합니다. 테스트가 어렵습니다. Race Condition은 재현이 어렵습니다. 정적 분석 도구(Thread Sanitizer)를 활용합니다. 처음부터 동시성을 고려한 설계가 중요합니다.
댓글
0