4. 병행 프로세스
1. 병행 프로세스의 개념
병행성 (Concurrency)
- 여러 개의 프로세스 혹은 스레드가 동시에 실행되는 시스템적 특성을 의미한다.
- 단일 CPU(코어) 환경에서는 짧은 시간 동안 번갈아가며 실행(시분할)되고, 다중 CPU 환경에서는 각 프로세스 혹은 스레드가 물리적으로 병렬 실행된다.
- 메모리 구조에 따라 강결합 멀티프로세서 혹은 약결합 멀티프로세서로 나뉜다.
- 강결합 (Tightly Coupled): 여러 CPU가 하나의 메모리를 공유 (하나의 운영체제)
- 약결합 (Loosely Coupled): 각 시스템이 독립된 운영체제와 메모리를 가지고 서로 통신 링크를 통해 연결됨
단일 프로세스 내의 병행성
단일 프로세스 내에서 병행성은 우선순위 그래프, Fork/Join 구조, 병행문 등을 통해 구현 및 설명된다.
프로세스 간의 병행성
- 프로세스 간의 병행성에서 자원을 공유하며 상호 협력하는 경우를 협력 프로세스(Cooperating Process) 라고 한다.
- 비동기 병행 프로세스는 서로 자원을 공유하며 실행 결과에 영향을 미칠 수 있다.
2. 동기화와 임계 영역
- 프로세스 동기화란 2개 이상의 프로세스의 처리 순서를 결정하는 것을 말한다.
- 임계 영역(Critical Section) 이란, 프로세스가 공유 변수를 읽거나, 테이블을 갱신하거나, 파일에 쓰는 등의 작업을 하는 코드 세그먼트를 의미한다.
임계 영역을 갖는 프로세스의 일반적 구조는 다음과 같다.
- 진입 영역: 임계 영역에 진입할 수 있는지 확인
- 해제 영역: 임계 영역에서 작업을 마치고 다른 프로세스의 진입을 허용
- 잔류 영역: 나머지 영역
임계 영역의 동기화 문제를 해결하기 위해서는 다음과 같은 조건이 필요하다.
- 상호 배제 (Mutual Exclusion): 서로 다른 프로세스가 임계 영역에서 동시에 작업을 할 수 없다.
- 진행 (Progress): 임계 영역에 진입할 프로세스를 적절히 선택해야 하며, 이 결정은 무한히 미루어질 수 없다.
- 한계 대기 (Bounded Waiting): 어떤 프로세스가 임계 영역 진입을 요청한 후, 다른 프로세스들이 진입하는 횟수에 제한을 두어야 한다. (기아 방지)
Test-and-Set (TS)
- 상호 배제의 하드웨어적 해결 방법이며, 분리가 불가능한 단일 기계어 명령어이다.
- 메모리 내의 하나의 비트를 key로 사용하여 busy 상태를 표현한다.
- 다른 프로세스가 임계 영역에 진입하기 전에, 해당 영역이 점거 상태인지 체크하고 사용이 끝난 프로세스는 key 비트를 0으로 리셋해준다.
- 모든 절차는 인터럽트 되지 않게 원자적(Atomic)으로 수행된다.
TS 메커니즘의 결점:
- 많은 프로세스가 동시에 임계 영역에 들어가기를 원하면 '기아(Starvation)' 상태가 발생할 수 있다. (스레드가 필요한 자원을 할당받지 못하고 계속 대기함)
- 대기 프로세스는 비생산적이고 자원만 소비하는 Busy Waiting 상태에 놓이게 된다.
세마포어 (Semaphore)
- TS 기법보다 조금 더 일반화에 용이하도록 다익스트라(Dijkstra)가 제시한 동기화 도구이다.
- 검사 연산인
P(s)연산과 증가 연산인V(s)연산으로 나누어진다. - P, V 연산은 각각 원자적 연산으로 간주된다. (도중에 인터럽트 되지 않는다.)
- P(s) (Wait): 세마포어 값을 1 감소시킴. (값이 0보다 작으면 대기) -> 자원 획득 시도
- V(s) (Signal): 세마포어 값을 1 증가시킴. (대기 중인 프로세스가 있다면 깨워줌) -> 자원 반납
3. 프로세스의 상호 협력
- 몇 개의 프로세스가 공통 작업을 수행하기 위해 서로 협동하는 경우가 있다.
- 대표적인 예제로 생산자-소비자 문제, 판독기-기록기 문제가 있다.
생산자와 소비자 문제
생산자 소비자 문제
- 개요: 고정된 크기를 가진 버퍼를 사이에 두고, 버퍼가 비어 있다면 소비자가 기다리게 되고 버퍼가 가득 차게 되면 생산자가 기다리게 된다.
- 상호 배제: 한 순간에 한 프로세스만 버퍼를 사용해야 한다.
- 동기화: 생산이 이루어져야 소비가 이루어지며, 버퍼 용량 이상으로 생산하면 안 된다.
생산자 프로세스 의사코드
repeat
// ...
// nextp에 데이터 항목을 생산함
// ...
P(empty);
P(mutex);
// ...
// nextp를 버퍼에 넣음
// ...
V(mutex);
V(full);
until false;
> 이 시리즈의 모든 포스팅은 직접 수업과 교재를 통해 학습한 내용을 토대로
> 손으로 정리한 후, **AI를 이용해 구조 정리와 맞춤법만 다듬은 자료**입니다.