[Pintos 9주차 키워드] semaphore와 mutex
들어가기에 앞서
교착상태(Deadlock
)와 임계 영역(Critical Section
)라는 키워드를 이해해야한다.
사람 A와 사람 B에겐 물컵🥛과 물통🫖이 있다.
(물컵🥛과 물통🫖이 둘 다 있어야 물을 마실 수 있다고 가정하자)
사람 A는 물을 따라마시기 위해 물컵🥛을 먼저 챙겼고,
사람 B는 물을 따르기 위해 물통🫖을 먼저 챙겼다.
그럼 사람 A는 물통🫖을 기다리고 있고, 사람 B는 물컵🥛을 기다리고 있다.
서로가 서로 들고 있는 물통🫖 or 물컵🥛을 기다리며 무한 대기 상태에 빠진다.
이것이 바로 교착상태이다.
물컵🥛과 물통🫖은 공유자원인데 이러한 공유자원 때문에 교착상태가 발생할 수 있는 부분을 임계 영역이라고 한다.
이처럼 교착상태가 발생하려면 아래의 4가지 조건이 모두 동시에 만족해야한다.
이 4가지 조건 중 하나라도 충족되지 않으면 교착상태는 발생하지 않는다.
상호배제(
Mutual Exclusion
)- 하나의 프로세스가 공유자원(물컵&물통)을 사용할 때, 다른 프로세스가 동일한 공유자원에 접근할 수 없도록 통제
점유 대기(
Hold and Wait
)- 사람 A와 사람 B는 각각 물컵🥛과 물통🫖을 점유한 채, 다른 하나를 기다림
비선점(
No Preemption
)- 들고있는 물컵🥛 또는 물통🫖을 뺏을 수 없음
순환 대기(
Circular Wait
)- 사람 A는 사람 B가 가진 물통🫖을 기다리고, 사람 B는 사람 A가 가진 물컵🥛을 기다림
따라서 임계 영역에 여러 프로세스 및 스레드가 함부로 접근 못하도록 관리를 잘 해주기 위해 상호배제를 달성하는 기법이 필요하다. 세마포어(semaphore
)와 뮤텍스(mutex
)가 이를 위해 고안된 기법이다.
세마포어와 뮤텍스의 배경 - Race condition
Race condition이란 두 개 이상의 스레드/프로세스가 공통 자원을 동시에 읽거나 쓰는 동작을 할 때,
실행 타이밍이나 접근 순서에 따라 실행 결과가 달라지는 상황을 뜻한다.
즉, 두 개 이상의 프로세스 또는 스레드가 하나의 공유 자원을 놓고 서로 사용하려고 경쟁하는 상황을 뜻한다.
이 Race condition의 경우, 세 가지 제어 문제에 직면한다.
Mutual exclusion(상호 배제), deadlock(교착상태), starvation(기아상태) 이다.
- Mutual exclusion (상호 배제)
- 두 개 이상의 프로세스가 공유 자원에 동시에 접근 하는 것을 막아야함
- Deadlock (교착 상태)
- 두 개 이상의 프로세스가 서로 상대방이 가지고 있는 자원을 기다리기만 하면서 무한 대기에 빠지는 상태
- Starvation (기아 상태)
- 특정 스레드가 자원에 접근할 기회를 계속 박탈당해 영원히 실행되지 못하는 상태
- 우선순위가 낮거나 대기열에서 계속 밀려나는 경우 Starvation이 발생할 수 있음
이러한 문제를 해결하기 위해 프로세스 또는 스레드 간의 동기화(synchronization) 개념이 등장하게 되었다.
여기서 동기화란? 동시에 접근하지 못하도록 접근순서를 제어하는 방식이다.
대표적인 동기화 도구로 세마포어와 뮤텍스가 있다.
각각의 개념을 자세히 살펴보자.
세마포어(semaphore)란?
공유된 자원의 데이터 or 임계 영역에 여러 프로세스나 스레드가 접근하는 것을 막아준다. (동기화 대상이 하나 이상)
세마포어는 내부적으로 정수 값(S)을 가지며, 이 값을 기반으로 스레드가 자원에 접근 가능한지를 결정한다.
- S > 0 : 접근 가능한 자원 있음 ➔ 접근 가능
- S = 0 : 접근 가능한 자원 없음 ➔ 대기 필요
wait()
, signal()
이 두 함수를 사용해 여러 프로세스들이 공유 자원에 대한 접근을 처리한다.
wait()
는 자원 사용을 요청하고, signal()
은 자원 사용을 마쳤음을 알린다.
wait()
: 세마포어 값을 -1 감소시키고, 값이 0보다 작아지면 대기 상태에 들어감signal()
: 세마포어 값을 +1 증가시키고, 대기 중인 프로세스가 있으면 하나를 깨워서 자원을 사용하게 함
예를 들어 세마포어를 식당 화장실에 비유해보자.
이 화장실에는 여러 개의 칸이 있고, 입구 전광판에는 현재 빈 칸의 수(S)가 표시된다고 가정하자.
화장실에 가고 싶은 사람은 전광판을 확인하여 빈칸이 있다면wait()
연산으로 칸 수를 -1 해준 뒤 입장
화장실을 다 쓴 뒤에는signal()
연산으로 칸 수를 +1 하며 나감
빈 칸이 없으면(S=0
) 다음 칸이 비워질 때까지 기다려야 함
- 화장실 이용하는 사람 : 스레드/프로세스
- 화장실 : 공유자원
- 전광판의 수치(S) : 세마포어 값
세마포어 특징
- 소유권 없음 : 자원을 점유한 스레드와 해제하는 스레드가 달라도 됨
- 자원 수 제어 가능 : 여러 개의 자원을 제어할 수 있어서 유연성이 큼
뮤텍스(mutex)란?
mutex는 mutual
+ Exclusion
의 합성어로, 상호 배제의 약어이다.
임계 영역을 가진 스레드들의 실행시간이 서로 겹치지 않고 각각 단독으로 실행되도록 한다. (동기화 대상이 하나)
오직 하나의 스레드만이 동일한 시점에 뮤텍스를 얻어 임계영역에 들어올 수 있다.
그리고 오직 이 스레드만이 임계영역에 나갈 때 뮤텍스를 해제할 수 있다.
예를 들어, 뮤텍스를 화장실 키에 비유해보자.
화장실이 딱 하나뿐인 식당에서, 화장실을 사용하려면 문을 열 수 있는 하나의 열쇠(뮤텍스 키)가 필요함
열쇠를 가진 사람만이 화장실(공유 자원)을 사용가능하고, 사용을 마치고 열쇠를 돌려줘야 다음 사람이 사용 가능
- 화장실 이용하는 사람 : 스레드/프로세스
- 화장실 : 공유자원
- 화장실 키 : 자원에 대한 접근 권한
세마포어와 뮤텍스의 차이점
동기화 대상의 개수
뮤텍스는 동기화 대상이 오직 하나일 때 사용한다.
세마포어는 동기화 대상이 하나 이상일 때 사용한다.자원의 소유권
뮤텍스는 소유 개념이 있다. 뮤텍스를 획득한 스레드만이 해당 뮤텍스를 해제(unlock)할 수 있다.
반면 세마포어는 소유 개념이 없다. 따라서 획득한 스레드가 아닌 다른 스레드도 해제(signal) 할 수 있다.운영 범위와 시스템 자원
뮤텍스는 일반적으로 프로세스 내부에서 사용되며, 프로세스 종료 시 자동으로 해제된다.
세마포어는 시스템 범위에서 사용될 수 있으며, 파일 시스템 기반으로 존재하기도 한다.