포도가게의 개발일지

Mutex vs Semaphore vs Monitor 본문

CS

Mutex vs Semaphore vs Monitor

grape.store 2021. 12. 27. 23:32
반응형

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