다중프로세스 설계에서 동기화와 IPC를 다루는 법

다중프로세스 환경에서 경쟁 조건, IPC, 교착 상태, 캐시 일관성, NUMA와 성능 최적화 시 고려할 설계 원칙을 정리한다.

2026-08-14 · 최초 발행 2026-01-16

동시에 실행되는 작업이 만드는 설계 조건

다중프로세스 시스템은 2개 이상의 프로세스가 동시에 또는 병렬로 실행되는 환경이다. 단일 프로세서의 시분할 실행과 다중 프로세서의 물리적 병렬 실행을 모두 포괄한다.

이 환경에서는 메모리, 파일, 장치 같은 자원을 여러 실행 주체가 함께 쓸 수 있다. 실행 순서는 고정되지 않으므로, 동시성·병렬성·자원 공유·비결정성을 전제로 설계해야 한다.

다중 프로세서프로세스 ACPU 0프로세스 BCPU 1프로세스 CCPU 2병렬 실행(병렬성)단일 프로세서프로세스 A시분할프로세스 B프로세스 C순차 실행(동시성)

프로세스는 각자 독립된 메모리 공간을 갖고, 스레드는 같은 프로세스의 메모리를 공유한다. 이 차이는 생성과 전환 비용뿐 아니라 통신 방식, 장애 격리, 동기화 난이도에도 영향을 준다.

구분 프로세스 스레드
메모리 공간 독립적 공유
생성 비용 높음 낮음
컨텍스트 스위칭 무거움 가벼움
통신 방식 IPC 필요 공유 메모리
안정성 높음(격리) 낮음(영향 전파)
동기화 복잡도 상대적 단순 복잡

공유 자원을 안전하게 다루기

경쟁 조건(Race Condition)은 여러 프로세스가 공유 자원에 함께 접근할 때, 실행 순서에 따라 결과가 달라지는 현상이다. 공유 자원이 존재하고 동시 접근이 가능하며, 최소 하나의 쓰기 연산이 있고 원자적 연산이 보장되지 않을 때 발생할 수 있다.

// 공유 변수 counter = 5

// 프로세스 A              // 프로세스 B
read counter  (5)         read counter  (5)
counter + 1   (6)         counter - 1   (4)
write counter (6)         write counter (4)

// 예상 결과: 5, 실제 결과: 4 또는 6 (비결정적)

공유 자원에 접근하는 코드는 임계 영역(Critical Section)으로 취급한다. 한 번에 하나의 프로세스만 들어가도록 보장해야 하며, 상호 배제, 진행, 한정 대기를 만족해야 한다. 상호 배제는 하나만 진입하게 하고, 진행은 무한 대기를 막으며, 한정 대기는 기아를 방지한다.

아니오프로세스 진입 요청임계 영역비어 있음?진입 섹션(락 획득)임계 영역(공유 자원 접근)퇴출 섹션(락 해제)나머지 영역대기

뮤텍스는 이진 세마포어의 특수 형태로 소유권 개념을 가지며, 획득한 프로세스만 해제할 수 있다. 세마포어는 카운팅 방식으로 복수 자원을 관리하거나 이진 방식으로 뮤텍스와 유사하게 사용할 수 있고, P(wait)와 V(signal) 연산을 사용한다. 모니터는 조건 변수를 포함하는 고급 동기화 구조이며 Java synchronized와 Python Lock처럼 언어 수준에서 지원될 수 있다.

메커니즘 특징 사용 사례
스핀락 바쁜 대기, 짧은 임계 영역 커널, 인터럽트 핸들러
뮤텍스 슬립 대기, 소유권 있음 일반 응용 프로그램
세마포어 카운팅 가능, 신호 전달 생산자-소비자 패턴
조건 변수 복잡한 조건 대기 모니터 내부
읽기-쓰기 락 다중 읽기, 단일 쓰기 읽기 빈번한 데이터

주소 공간 밖의 프로세스와 협력하기

독립된 주소 공간을 쓰는 프로세스가 데이터를 교환하거나 협력하려면 IPC(Inter-Process Communication)가 필요하다.

파이프는 부모-자식 프로세스 사이의 단방향 스트림 통신에 쓰이며, 익명 파이프와 명명 파이프(FIFO)가 있다. 메시지 큐는 구조화된 메시지를 비동기로 전송하고 POSIX 및 System V 방식을 지원한다. 공유 메모리는 같은 물리 메모리를 매핑하므로 대용량 데이터에 적합하지만 별도의 동기화가 필요하다. 소켓은 TCP/UDP 프로토콜을 사용해 원격 프로세스까지 양방향으로 연결할 수 있다.

IPC 메커니즘파이프단방향부모-자식메시지비동기구조화 메시지공유 메모리고속대용량소켓네트워크양방향프로세스 A프로세스 B

선택할 때는 통신 속도와 용량, 구현 복잡도, 네트워크 연결 필요 여부, 동기화 책임을 함께 봐야 한다.

기준 파이프 메시지 큐 공유 메모리 소켓
속도 보통 보통 매우 빠름 느림
용량 제한적 제한적 대용량 가변
복잡도 낮음 중간 높음 중간
네트워크 불가 불가 불가 가능
동기화 내장 내장 별도 필요 내장

자원 대기가 멈추지 않을 때

교착 상태(Deadlock)는 2개 이상의 프로세스가 상대방이 점유한 자원을 기다리며 무한히 대기하는 상태다. 상호 배제, 점유와 대기, 비선점, 순환 대기라는 4가지 조건이 모두 충족될 때 발생한다.

자원 2 요청자원 1 요청대기대기프로세스 A(자원 1 점유)자원 2(B가 점유)프로세스 B(자원 2 점유)자원 1(A가 점유)

예방은 필요 조건 가운데 하나를 부정하는 방식이다. 공유 가능한 자원을 사용하거나, 모든 자원을 일괄 요청하게 하거나, 자원 강제 회수를 허용하거나, 자원 순서화를 적용할 수 있다.

회피는 안전 상태를 유지하도록 자원 할당을 결정한다. 은행원 알고리즘(Banker's Algorithm), 자원 할당 그래프를 사용하며 최대 자원 요구량을 사전에 알아야 한다. 탐지 및 복구는 교착 상태를 허용한 뒤 대기 그래프 분석, 프로세스 종료, 자원 선점, 체크포인트/롤백으로 복구한다.

전략 오버헤드 자원 활용도 적용 용이성
예방 높음 낮음 쉬움
회피 중간 중간 어려움
탐지/복구 낮음 높음 중간
무시 없음 최고 매우 쉬움

메모리와 캐시가 병목이 되는 지점

가상 메모리는 각 프로세스에 독립적인 가상 주소 공간을 제공한다. 페이지 테이블 관리, 페이지 폴트 처리, 스와핑 정책, Copy-on-Write 최적화가 여기에 포함된다.

공유 메모리가 필요하다면 mmap, shmget 시스템 콜로 명시적으로 매핑한다. 이 경우 동기화 메커니즘과 메모리 일관성 유지는 별도로 처리해야 한다.

다중 프로세서에서는 CPU별 캐시의 일관성도 관리 대상이다. MESI 프로토콜은 Modified, Exclusive, Shared, Invalid 상태로 캐시 복사본을 관리한다. Modified는 수정된 유일한 복사본이고, Exclusive는 메모리와 일치하는 배타적 복사본이며, Shared는 읽기 전용 공유 상태, Invalid는 무효 상태다.

캐시 일관성CPU 0캐시버스스누핑CPU 1캐시CPU 2캐시메인 메모리MESI 프로토콜무효화 기반

False Sharing은 서로 다른 변수가 같은 캐시 라인에 있어 불필요한 캐시 무효화가 생기는 현상이다. 패딩을 추가하거나 캐시 라인을 정렬하고, 스레드 로컬 변수를 사용해 줄일 수 있다.

CPU와 메모리 위치를 함께 고려하는 스케줄링

대칭 다중 처리(SMP)에서는 모든 프로세서가 동등하게 스케줄링에 참여한다. 글로벌 런큐 또는 프로세서별 런큐를 두고, 부하 분산과 캐시 친화성을 고려한다.

프로세서 친화성(Affinity)은 프로세스를 특정 프로세서에 바인딩해 캐시 효율을 높이는 방법이다. 소프트 친화성은 힌트 수준이고, 하드 친화성은 강제 바인딩이며, CPU 집합(cpuset)을 활용할 수 있다.

NUMA(Non-Uniform Memory Access)는 프로세서 위치에 따라 메모리 접근 시간이 달라지는 구조다. 로컬 메모리를 우선 할당하고 원격 메모리 접근을 최소화하며, NUMA-aware 스케줄링을 적용한다.

NUMA 구조노드 1노드 0인터커넥트(느림)CPU 2, 3CPU 0, 1로컬 메모리로컬 메모리

병렬 처리의 이점을 유지하는 방법

작업은 데이터를 나눠 같은 연산을 수행하는 데이터 병렬화, 서로 다른 작업을 병렬 수행하는 작업 병렬화, 단계를 나눠 처리하는 파이프라인 병렬화로 분할할 수 있다. 확장성을 판단할 때는 순차 부분의 병목을 다루는 암달의 법칙, 문제 크기 증가를 고려하는 구스타프슨의 법칙, 강한 확장성과 약한 확장성을 함께 검토한다.

락 경합을 줄이려면 세분화된 락, 락 프리 자료구조, 읽기-쓰기 락을 사용할 수 있다. 락 프리 프로그래밍에서는 CAS, FAA 같은 원자적 연산과 메모리 순서 보장이 필요하며 ABA 문제에 주의해야 한다.

기법 장점 단점
거친 락 단순함 높은 경합
세분화 락 병렬성 향상 복잡도 증가
읽기-쓰기 락 읽기 병렬화 쓰기 기아 가능
락 프리 데드락 없음 구현 어려움
트랜잭셔널 메모리 직관적 하드웨어 의존

재현이 어려운 문제를 검증하는 방식

다중프로세스 버그는 실행 순서가 고정되지 않아 재현이 어렵다. 관찰 자체가 동작을 바꾸는 하이젠버그와 실행 환경에 따라 달라지는 타이밍 의존성도 진단을 어렵게 만든다.

정적 분석으로 경쟁 조건, 교착 상태 가능성, 락 순서를 점검할 수 있다. 동적 분석에서는 ThreadSanitizer로 데이터 레이스를, Valgrind로 메모리 오류를 탐지하고 실행을 추적해 재현한다. 부하 증가 테스트, 타이밍 변형 주입, 퍼즈 테스팅도 동시성 문제를 드러내는 데 사용된다.

다중프로세스동기화IPC교착 상태NUMA