[OS] Semaphore란? (Feat.상호배제 방법 - 뮤텍스(Mutex)와 모니터(Monitor)까지) - 1편
세마포어(Semaphore)란?
멀티 프로그래밍 환경에서 공유 자원에 대한 접근을 제한하는 방법
공유된 자원의 데이터 혹은 임계구역(Critical Section) 등에 여러 Process 혹은 Thread가 동시에 접근하면서 발생될 수 있는 문제를 방지하기 위하여 한 번에 하나의 프로세스만 접근할 수 있도록 제한을 두는 방법입니다. 이를 위해 사용하고 있는 스레드나 프로세스의 수를 공통으로 관리하는 하나의 값(공유변수)을 이용해 상호 배제를 달성할 수 있도록 합니다.
상호 배제(Mutual Exclusion)란?
멀티 프로그래밍에서 공유 불가능한 자원의 동시 사용을 피하기 위해 사용하는 알고리즘
임계 구역으로 불리는 코드 영역에 의해 구현된다.
= 하나의 프로세스가 공유 자원을 사용할 때 다른 프로세스의 접근을 막는 것이다.
- 상호 배제 알고리즘
- 데커 알고리즘
- 피커슨 알고리즘
- 제과점 알고리즘
- 상호 배제는 교착상태의 4가지 필요조건 중 하나
- 상호 배제 : 배타적 통제권(동시 사용 불가)
- 점유 대기 : 할당된 자원을 가진 상태에서 다른 자원을 기다림
- 비선점 : 다른 프로세스가 선점하고 있는 자원을 뺏을 수 없음
- 순환대기 : 각 프로세스는 순환적으로 다음 프로세스가 요구하는 자원을 가지고 있는 상황
- 교착 상태와 기아 상태
- 교착 상태 (DeadLock) : 무한 대기
- 기아 상태 (Starvation) : 우선 순위가 낮아 자원을 계속 할당받지 못하는 상태
- 멀티 프로세스나 멀티 스레드 동기화에 사용된다
- 동기화 (Synchronize) : 상호 배제를 위해 프로세스/스레드들의 실행을 제어하는 것.
-> 여기에 세마포어, 뮤텍스, 모니터 개념이 적용된다
임계구역 (Critical Section) 이란?
공유자원에 접근하는 프로세스 내부의 코드 영역
어떤 한 프로세스가 이 구역을 사용중일 때 다른 프로세스가 같은 구역을 사용(접근)하려 한다면 문제가 발생할 수 있다
따라서 문제가 발생하지 않도록 한번에 하나의 프로세스만 이용하게끔 보장해야 하는 영역이다.
- 임계 구역 문제 해결을 위한 3가지 조건
- 상호배제
하나의 프로세스가 임계 구역에 들어가있다면 다른 프로세스는 들어갈 수 없어야 함 - 진행
임계 영역에 들어간 프로세스가 없는 상태에서 들어가려 하는 프로세스가 여러개라면 어느 것이 들어갈 지 결정해주어야 함 - 한정 대기
다른 프로세스의 기아(Starvation)을 방지하기 위해, 한 번 임계 구역에 들어간 프로세스는 다음번 임계 구역에 들어가려고 할 때 제한을 두어야 함
- 상호배제
- 임계 구역의 동시 접근을 해결하기 위한 방법
- 세마포어(Semaphore)
- 락(Lock)
- 모니터(Monitor)
세마포어 접근 함수 - wait(), signal()
wait과 signal을 통해 구현된다
(P 연산, V 연산이라는 말도 존재하는데, 여기에서 P,V란 wait과 signal이란 네덜란드에서 나온 것으로 의미는 동일하다.)
- wait()
- 동작 방식
- 사용 가능한 공유 자원이 없다면 기다림
- 사용 가능한 공유 자원이 있다면 세마포어 변수를 -1 처리한 후 사용
- 임계 구역에 진입하기 전에 수행 (프로세스 진입 여부를 자원의 개수(S)를 통해 결정함)
- 동작 방식
- signal()
- 동작 방식
- 공유 자원을 모두 사용한 후에 세마포어 변수를 +1 처리함
- 공유 자원 사용을 완료했다는 신호를 보냄
- 임계 구역에서 나올 때 수행 ( 자원 반납 알림, 대기 중인 프로세스를 깨우는 신호)
- UNIX의 signal 호출과는 다르다
- 동작 방식
// Shared Data
semaphore mutex; // 세마포어 변수 mutex의 초기값은 자원의 갯수를 의미.
// Process P
do {
wait(mutex);
/* critical section */
signal(mutex);
/* remainder section */
} while (1);
- wait()과 signal()구현
// fun wait()
fun wait(S) {
while(S <= 0);
S--;
}
// fun signal()
fun signal(S) {
S++;
}
위 방식의 문제점
- Busy-wait (Spin-lock) 현상이 여전히 존재한다
- Block & Wake-Up (Sleep Lock)방식으로 해결가능
= 자원이 없을 때, Block 됐다가, 자원이 생기면 깨어남
Block / Wake-Up
Semaphore를 다음과 같이 정의했을 때
typedef struct
{
int value; // semaphore
struct process *L; // process wait queue
} Semaphores
Block과 Wake-Up을 다음과 같이 가정
- Block
- 커널은 Block을 호출한 프로세스를 Suspend(지연)시킴
- 이 프로세스의 PCB를 Semaphore에 대한 wait queue에 넣음
- Wakeup(P)
- Block된 프로세스 P를 WakeUp 시킴
- 이 프로세스의 PCB를 Ready queue로 옮김
- block/wakeup 버전의 wait(), signal()
P(S) {
S.value--; // Critical Section 들어갈 준비
if(S.value < 0) { // 음수면 못 들어감, Block 상태
add this process to S.L;
block();
}
}
signal(S) {
if(S.value <= 0) { // 자원을 내놓았는데도
remove a process P from S.L; // 자원이 0 이하라는 것은, 다른 누군가 (프로세스)가 잠들어있는 놈들이 존재한다는 것
wakeup(P);
}
}
여기서 음수라는 것은 누군가 자원을 쓰기 위해 기다리고 있다는 의미
Block / Wake-Up 과 Busy-wait의 장단점에 따른 적용 기준
- critical section 길이가 길면, Block/wakeup이 적당
- critical section 길이가 매우 짧으면, busy-wait가 적당
세마포어의 두 가지 종류
1. 계수형 세마포어 (counting semaphore)
0과 1의 값을 가지는 이진형 세마포어(binary semaphore)와 달리, 풀에 있는 자원의 수와 같은 값으로 초기화 되는 동기화 기법
- 동작 메커니즘
- 세마포어는 Pool 자원 수와 같은 값으로 초기화
- P 호출이 발생할 때 마다 세마포어 1씩 감소, Pool 자원이 추가 할당되어 스레드에서 사용 표시
- V 호출은 세마포어 1씩 증가시켜 스레드가 자원을 Pool로 반납, 자원을 다른 스레드에 할당 가능 표시
- 세마포어가 0까지 줄어들었을 때 스레드가 P 호출 시 스레드는 V 통해 자원을 Pool로 반납 시까지 대기
- 구성 요소
구분 | 구성요소 | 세부 내용 |
계수범위 | 음수 | 세마포어에 정확한 -N개의 스레드 큐가 존재 |
0 | 대기중인 스레드가 없으며, wait 연산은 호출 스레드를 큐에 추가 | |
양수 | 대기중인 스레드가 없으며, wait 연산은 호출 스레드를 큐에 추가 안함 | |
연산자 | wait() | 세마포어 카운터 감소, 결과로 음수가 되고 호출 스레드는 큐에 삽입 |
signal() | 세마포어 카운터 증가, 결과로 양수가 되고 대기 중 스레드는 큐에서 제거 |
2. 바이너리 세마포어 (Binary Semaphore)
이진 세마포어의 값은 0과 1사이의 값만 가능하며 뮤텍스 락과 유사하게 동작함
- 동작 메커니즘
- 상호 배제를 위해 신호 전달 메커니즘을 사용해서 잠금을 구현
- 세마포어가 0이면 잠겨있고 1이면 잠금이 해제되어있는 것을 의미
세마포어 동기화 기법 비교
구분 | 이진형세마포어 | 계수형세마포어 | 뮤텍스 |
Internal States | 2 | N | 2 |
User from ISRs | Yes | Yes | No |
Ownership | No | No | Yes |
Priority Inheritance | No | No | Yes |
Initialization | 없을 수도 있음 | Counter >= 0 | 항상 가지지 않음 |
Queue 구성 | FIFO or 우선순위 | FIFO or 우선순위 | 우선순위 |
Reference
https://velog.io/@youngminss/OS-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-%EB%8F%99%EA%B8%B0%ED%99%942
[OS] 프로세스 동기화(2)
= lock/unlock 기능, 공유 자원을 획득하게 해준다.앞선, 일반 방식들을 추상화시킨 것Semaphore S == 자원의 갯수Integer variable두 가지 Atomic 연산에 의해서만 접근이 가능함Critical Section of n Processsem
velog.io
계수형 세마포어 (Counting Semaphore) > 도리의 디지털라이프
I. 멀티 프로세스 환경의 리소스풀, 계수형 세마포어의 개념 0과 1의 값을 가지는 이진형 세마포어와 달리, 풀에 있는 자원의 수와 같은 값으로 초기화 되는 세마포어 동기화 기법 II. 계수형 세
blog.skby.net