포도가게의 개발일지
Mutex vs Semaphore vs Monitor 본문
반응형
Race Conditions?
- multi thread 환경을 구축하게 되면 동시성 문제가 항상 뒤따라 온다.
- 여러 thread가 경쟁적으로 shared state에 접근한 탓에, 접근 순서에 따라 그 결과가 달라지는 상황을 의미
Atomic Operation
- Race condition을 막기 위해서는 각 thread의 접근이 atomic하게 이루어져야 한다.
atomic하게 이뤄진다는 것은 기능적으로 분할할 수 없거나 분할하지 못하도록 보증된 동작을 의미한다.
- 동시성 프로그래밍의 가장 큰 숙제는 ‘공유자원 관리’일 것이다. 공유자원을 안전하게 관리하기 위해서는 상호배제(Mutual exclusion)를 달성하는 기법이 필요하다.
뮤텍스: 한 쓰레드, 프로세스에 의해 소유될 수 있는 Key 를 기반으로 한 상호배제기법
- 임계구역(Critical Section)을 가진 스레드들의 실행시간(Running Time)이 서로 겹치지 않고 각각 단독으로 실행(상호배제_Mutual Exclution)되도록 하는 기술
- 한 프로세스에 의해 소유될 수 있는 Key를 기반으로 한 상호배제 기법
- Key에 해당하는 어떤 객체(Object)가 있으며, 이 객체를 소유한 스레드/프로세스만이 공유자원에 접근할 수 있다.
세마포어: Signaling mechanism. 현재 공유자원에
접근할 수 있는 쓰레드, 프로세스의 수를 나타내는 값을 두어 상호배제를 달성하는 기법
- P는 임계 구역에 들어가기 전에 수행되고, V는 임계 구역에서 나올 때 수행된다. 이때 변수 값을 수정하는 연산은 모두 원자성을 만족해야 한다. 다시 말해, 한 프로세스(또는 스레드)에서 세마포어 값을 변경하는 동안 다른 프로세스가 동시에 이 값을 변경해서는 안 된다.
계수 세마포어
- 계수 세마포어(counting semaphore)에서는 초기값은 가능한 자원의 수로 정해지며, 세마포어 값의 범위는 정해져 있지 않다.
이진 세마포어
- 이진 세마포어(binary semaphore)에서는 세마포어 값으로 0 또는 1을 가진다. 계수 세마포어보다 간단히 구현할 수 있으며, Test and Set 등 하드웨어가 지원하는 기능을 이용하여 구현하기도 한다. 또한, 이진 세마포어를 이용하여 계수 세마포어를 구현할 수도 있다.
모니터
- 세마포어 이후 프로세스 동기화 도구
동작
- 공유자원 + 공유자원 접근함수로 구성됨
- 2개의 queues: 배타동기(Mutual exclusion queue) + 조건동기(Conditional synchronization)
- 공유자원 접근함수에는 최대 1개의 쓰레드만 집입가능: 나머지는 큐에서 진입못하고 기다리고 있어야한다.(Mutual exclusion queue에서 대기)
- 진입 쓰레드가 조건 동기로 블록되면 새 쓰데르 진입가능: wait call> 들어왔던 쓰레드는 Conditions synchronization에 갇히게 된다. 그러면 새 쓰레드가 진입가능하다.
- 새 쓰레드는 조건동기로 블록된 쓰레드를 깨울 수 있음: notify()> 블록된 쓰레드를 깨워준다.
- 깨워진 쓰레드는 현재 쓰레드가 나가면 재진입할 수 있음: 하나의 쓰레드만 있을 수 있으니까, 그 비어진 자리에 깨워진 쓰레드가 들어올 수 있게 된다.
## 철학자의 식사 문제
## synchronized -> Mutual exclusion queue 모니터에 들어가기 위한 lock
## inUse -> Conditional synchronization 젓가락 상태 컨디션
## mesa 디자인은 hoare와 달리 signal thread가 주도권을 다시 가져가기 때문에 while을 통한 check가 필요하다.
## hoare는 주도권을 바로 주긴하지만
## Spurious wakeup?이란 현상으로 인해 mesa style을 권장한다.
## -> signal을 하지 않았음에도 불구하고 thread가 깨어나버리는 현상을 말한다.
class Chopsticks {
private boolean inUse = false //아무도 젓가락을 사용하지 않겠지
synchronized void acquire() throws InterruptedException { //젓가락을 잡는것 acquire();
while (inUse) // 누군가가 젓가락을 집고있으면
wait(); // 기다리고 철학자는 갇혀있게 됨
inUse = true;
}
synchronized void release() { // 젓가락을 놓는것 release;
inUse = false;
notify(); // 누군가 큐에서 기다리고 있다면 깨워줘야지
}
}
'CS' 카테고리의 다른 글
정규 표현식 (0) | 2022.03.26 |
---|---|
Solid 원칙 (0) | 2022.01.31 |
Web Server (0) | 2021.12.25 |
동적 메모리 할당 분리가용 리스트 (0) | 2021.12.23 |
Buddy Memory Allocator란? (0) | 2021.12.21 |
Comments