프로세스 동기화의 필요성
어떤 프로세스가 먼저 공유 자원에 접근하느냐에 따라 실행 결과가 달라질 수 있기 때문에 공유 자원의 일관성을 유지하기가 어렵습니다. 이를 해결하기 위해 프로세스 동기화가 필요합니다.
1. 병행성(Concurreny) vs 병렬성(Parallelism)
1.1 병행이란?
동시에 실행되는 것처럼 보이는 것입니다. 자세하게는 메모리에 다수의 프로세스가 같이 존재한다는 의미입니다.
실제 실행 과정에서 자원을 공유하고 있을 경우 공유된 자원을 서로 언제 사용할것이지와 같은 복잡한 관리가 필요합니다.
병행 처리는 다음과 같은 문제점이 있습니다.
- 전역 자원의 공유가 어렵다.
- OS가 자원을 최적으로 할당하기 어렵다
- 프로그래밍 오류를 찾아내는 것이 어렵다.
1.2. 병렬이란?
실제로 동시에 작업이 처리가 되는것입니다. 따라서 멀티 코어에서만 가능합니다. 애플리케이션에서 작업을 여러 CPU에서 동시에 별렬로 작업할 수 있는 Process 단위로 분할합니다.
(병렬처리가 되기 위해선 병행성이 전제되어야만 합니다!)
2. Concurrent Process
병행 프로세스들의 비동기적 실행은 서로 공유된 자원이 없을땐 독립적으로 작업이 진행됩니다. 하지만 공유 자원이 있을 경우 '한번에 한 프로세스만 접근' 과 같은 규칙을 따라야 합니다.
- 경쟁 상태 (Race Condition) : 프로세스들이 공유 자원에 대해 서로 접근을 시도하는 상황을 의미합니다. 이러한 경쟁 상태에 있는 프로세스들로 인해 상호 배제, 교착 상태(Deadlock), 기아(Starvation)와 같은 문제가 발생하게 됩니다.
- 상호배제는 아래와 같은 네 가지 조건을 만족해야합니다.
- 두 프로세스는 동시에 공유 자원에 진입할 수 없다.
- 프로세스의 속도나 프로세서 수에 영향을 받지 않는다.
- 공유자원을 사용하는 프로세스만 다른 프로세스를 차단할 수 있다.
- 프로세스가 공유 자원을 사용하려고 너무 오래 기다려서는 안된다.
2.1. 상호 배제(Mutual Exclusion)
병행 프로세스 환경에서 프로세스 하나가 공유 자원을 사용할 때 다른 프로세스들이 자원에 접근하지 못하도록 하는 방법입니다.
읽기 연산은 공유 데이터에 동시에 접근해도 문제가 발생하진 않지만, 변수나 파일은 프로세스별로 하나씩 차례로 읽거나 쓰도록 해야합니다.
즉, 한번에 하나의 프로세스만이 임계 영역에 들어가야함을 의미합니다.
"공유 자원에 동시에 접근할때 이를 제어하는 동기화 작업이 필요합니다."
- 임계 영역(Critical Section)
멀티 프로세스 환경에서 반드시 하나의 프로세스만 접근할수있는 공유 자원의 코드 영역입니다.
임계 구역은 시간이 지나면 종료되며, 어떤 프로세스가 임계구역에 접근하기 위해서는 지정된 시간만큼 대기해야 합니다.
이때 스레드나 프로세스가 배타적인 사용권을 보장받기 위해 세마포어와 같은 동기화 메커니즘이 사용됩니다.
3. 동기화 기법
3.1. 세마포어(Semaphore)
- 공유된 자원의 데이터를 여러 프로세스가 접근하는 것을 막아주는 방법입니다.
- 상호 배제를 운영체제와 프로그래밍 언어 수준에서 지원하는 방법입니다.
- 세마포어를 공유자원의 개수를 나타내는 변수라고 생각할 수 있습니다.
- 세마포어 값을 초기화하는 명령, P명령, V명령이 있고 P와 V는 wait와 signal로 사용하기도 합니다.
- 특정 자원이나 특정 연산을 동시에 사용하거나 호출할 수 있는 스레드의 수를 제한하고자 할 때 사용 할 수 있습니다. → 자원 풀이나 컬렉션의 크기에 제한을 둘때 유용합니다.
다음과 같은 3가지 인터페이스로 구성됩니다.
- 초기화 연산 : 세마포어 값을 음이 아닌 값으로 초기화
- 대기 연산 : 세마포어 값을 감소시키며, 값이 음수이면 호출한 프로세스는 block. 음수가 아니면 프로세스는 계속 수행
- 시그널 연산 : 세마포어 값을 증가. 값이 양수가 아니면 block 된 프로세스를 깨움.
void P(S){
S--;
if(S < 0){
// 프로세스를 세마포어 큐에 넣는다
// 프로세스를 block
}else{
// S > 0이 될때까지 큐에서 대기
}
void V(S){
if(큐에서 대기중인 프로세스가 존재){
//세마포어 큐에 있는 하나의 프로세스를 꺼낸다
//꺼낸 프로세스를 wakeup
}else{
S++;
}
}
const int n; //프로세스의 수
semaphore S=1;
void p(int i){
while(true){
P(S);
//critical section
V(S);
//임계 영역 이후 코드
}
}
3.2. 뮤텍스(Mutex)
- 공유 자원에 여러 스레드가 접근하는 것을 막는 방법입니다.
- 임계 영역을 가진 스레드들의 Running time이 서로 겹치지 않게 각각 단독으로 실행되게 하는 기법. → Mutex 객체를 두 스레드가 동시에 사용 할 수 없음을 의미
- 임계 영역에 진입할때 lock을 걸어 다른 프로세스가 접근하지 못하게 하고 임계영역에서 탈출할때 lock을 해제하여 공유 자원에 여러 스레드가 접근하는것을 막는 것.
3.3. 세마포어 vs 뮤텍스
- 뮤텍스는 하나의 스레드(프로세스)에 의해 소유될 수 있는 Key를 기반으로 한 상호 배제 기법입니다. 세마포어는 Signaling mechanism 으로 현재 공유자원에 접근할 수 있는 스레드, 프로세스의 개수를 나타내는 값을 두어 상호 배제를 달성하는 기법입니다.
- 세마포어는 공유자원에서 세마포어의 변수만큼 프로세스가 접근 가능합니다. 뮤텍스는 오직 1개의 프로세스만 접근 가능합니다
- 세마포어는 현재 수행중인 프로세스가 아닌 다른 프로세스가 세마포어를 해제할 수 있습니다. 뮤텍스는 lock을 획득한 프로세스만 unlock 시킬 수 있습니다.
'CS Study > Operating System' 카테고리의 다른 글
메모리 관리 - 메모리 단편화, 페이징, 세그멘테이션 (0) | 2021.03.24 |
---|---|
Thread란? Multi-Thread, Multi-Tasking, Multi-Processing (0) | 2021.03.03 |
프로세스란? PCB, Process State, Process Life Cycle (0) | 2021.03.01 |
Interrupt 란? 인터럽트 프로세스, 인터럽트 우선순위 (0) | 2021.02.26 |