Mutex (뮤텍스)
: 공유 자원에 대해 동시에 접근해서는 안되는 자원에 동시에 접근하지 않도로록 만드는 기법 즉, 상호 배제를 위한 동기화 도구이다.
Mutex 매커니즘은 하나의 전역 변수와 두 개의 함수로 구현할 수 있다.
# 뮤텍스 변수 초기화
lock = False
def acquire():
global lock
while lock == True:
lock = True
def release():
global lock
lock = False
# 뮤텍스 획득
acquire()
# --- critical section ---
# 뮤텍스 해제
release()
(위 코드는 while문에서 expected an indented block 에러 발생함)
위의 코드를 A와B라는 프로세스가 실행한다면
먼저 들어간 A가 실행이 끝나고 lock이 true가 될때까지 B는 while 반복문에서 대기해야한다.
A가 실행이 끝나고 release 함수를 실행하게되면 lock은 false가 되고 B는 반복문에서 빠져나올 수 있다.
이 코드에서 while 반복문은 반복적으로 lock의 상태를 계속 확인하게되는데
이런 대기 방식을 바쁜 대기(busy wait)
라고 한다
Semaphore (세마포어)
: 뮤텍스와 비슷하지만, 좀 더 일반화된 방식의 동기화 도구이다.
# 사용 가능한 공유 자원의 개수
S = 3
def P():
global S
while S <= 0:
S = S - 1
def V():
global S
S = S + 1
# 세마포어 획득
P()
# --- critical section ---
# 세마포어 해제
V()
(위 코드는 while문에서 expected an indented block 에러 발생함)
위 코드는 Mutex처럼 busy waiting이 발생한다.
이는 즉 CPU 주기를 낭비한다는 점에서 손해이다.
import threading
# 사용 가능한 공유 자원의 개수
S = 10
lock = threading.Lock()
condition = threading.Condition(lock)
def P():
global S
while S <= 0:
# 다른 스레드가 세마포어를 해제할 때까지 대기
condition.wait()
S = S - 1
def V():
global S
S = S + 1
# 세마포어를 해제한 후 대기 중인 스레드 깨우기
condition.notify()
# 세마포어 획득
P()
# --- critical section ---
# 세마포어 해제
V()
위 코드는 Busy wating(Spin-Lock)으로 구현한 세마포어와는 다르게 임계구역에 먼저 들어간 스레드가 끝난 후 condition.notify()로 세마포어를 해제하기 전까지 Busy wating하고 있는 것이 아닌 대기를 하게 된다.
일반적으로는 Sleep-Lock 으로 구현한 세마포어가 더 좋다.
하지만 임계구역의 길이가 매우 짧은 경우는 Sleep-Lock 오버헤드가 busy-wait 오버헤드보다 클 수 있다.
이진 세마포(binary semaphore)
카운팅 세마포(counting semaphore)
Monitor (모니터)
: 프로세스 또는 스레드를 동기화하는 방법 중 하나로서 사용자가 사용하기에 세마포어보다 훨씬 편리한 도구이다.
공유자원과 공유 자원에 접근하기 위한 인터페이스(통로)를 묶어서 관리한다.
프로세스는 반드시 인터헤이스를 통해서만 공유 자원에 접근하도록 해야한다.
모니터는 상호 배제와 실행 순서 제어를 위한 동기화이다
상호 배제
① 모니터를 통해 공유 자원에 접근하고자 하는 프로세스를 큐에 삽입
② 큐에 삽입된 순서대로 하나씩 공유 자원 이용
➡ 모니터는 모니터에 진입하기 위한 큐를 만들고, 모니터 안에 항상 하나의 프로세스만 들어오도록 하여 상호 배제를 위한 동기화 제공
실행 순서 제어
① 특정 조건을 바탕으로 프로세스를 실행하고 일시 중단하기 위해 조건 변수(condition variable)
사용
조건 변수 : 프로세스나 스레드의 실행 순서를 제어하기 위해 사용하는 특별한 변수
- 조건변수.wait() : 대기 상태로 변경
- 조건변수.signal() : wait() 으로 대기 상태로 접어든 조건변수를 실행 상태로 변경
➡ 모니터는 조건 변수를 이용하여 프로세스 실행 순서 제어를 위한 동기화를 제공