[운영체제] 세마포어와 뮤텍스

Letmegooutside·2022년 1월 17일
0

운영체제

목록 보기
12/16

Semaphore (세마포어)

정수값을 갖는 변수이며 자원의 개수를 의미한다

동기화 기법 중 추상적인 방법이며 여러 프로세스들에 의해 공유되는 변수로 정의된다.
이 변수는 오직 waitsignal이라는 atomic한 연산에 의해서만 접근이 가능하다.

세마포어의 개수에 따라 counting semaphore(0~n, 시스템 내 가용한 자원의 수를 나타냄)와 binary semaphore(0 or 1 , 뮤텍스와 같음)로 나뉜다.

Busy-Wait 방식

자원이 모두 사용중이라면 프로스세가 wait하는 방식이다.

s = 자원의 수;

wait(s){
  while(s <= 0) ; //busy waiting s가 1 이상이면 빠져나옴
  s--; // 자원 획득
}

signal(s){
  s++; // 자원 반납
}

만약 자원의 여유가 생기면 s--를 통해 자원을 획득한다.
그리고 자원을 모두 사용했다면 s++을 통해 자원을 반납한다.

do {
   wait(s);
   //ciritical section
   signal(s);
  //remainder section
} while(1);

s를 1로 초기화 했을 때(사용가능한 자원의 개수로 초기화 한다), 처음 P1이 critical section에 진입하면 wait 연산을 거쳐서 s가 0이 된다.
이 때 다른 프로세스 P2가 진입하려 하면 s는 0이므로 P1이 ciritical section에서 나와서 signal 연산을 하기 전 까지 busy waiting을 하게 된다.

busy waiting : ciritical section에 진입시도를 반복하는 것

Block-Wakeup 방식

type struct{
  int value;         // Semaphore
  struct process *Q;      // Wait Queue
}semaphore;

이 방식은 먼저 위와 같이 세마포어를 정의한다.

wait(s){
 // 나 자원 쓸래
  s.value--;
 // 근데 없으면
  if(s.value < 0){
    // 큐에 걸어놓고 자고 있어야지
    // add this process to s.queue; 
    block();
  }
}

signal(s){
 // 나 다썼어
  s.value++;
 // 근데 없네 누가 쓰려고 큐에서 기다리나보다
  if(s.value <= 0){
    // remove a process P from s.queue;
    // 깨우기. 너 쓸 차례야
    wakeup(P);
  }
}

먼저 자원의 값을 감소시킨다.
만약 자원의 개수가 부족해 사용할 수 없다면 현재 프로세스를 wait queue에 추가시킨 후 block()을 통해 suspend시킨다.

만약 다른 프로세스가 작업을 완료하여 자원의 값을 증가시키며 반납했을 때, 자원의 수가 없다면 이는 현재 자원을 기다리는 프로세스가 존재한다는 뜻이다.
따라서 wait queue에서 프로세스를 꺼내와 wakeup()을 통해 깨우게 되는 것이다.

  • Busy-wait vs Block-wakeup
    ciritical secion의 길이가 긴 경우에는 block-wakeup방식이 유리하다.
    하지만 ciritical section의 길이가 짧다면 잦은 문맥 교환으로 인해 오버헤드가 증가하게 된다.
    따라서 반대의 경우에는 busy-wait방식이 유리하다.

Mutex (뮤텍스)

상호배제를 뜻하며 Binary Semaphore와 같은 의미이다. 따라서 자원에 단 하나의 작업만이 접근할 수 있다

운영체제 커널에 의해 제공되어 무겁고 느리다.

mutex = 1;

void lock () {
   while (mutex != 1) {
       // mutex 값이 1이 될 때까지 기다린다
    }
    // 이 구역에 도착했다는 것은 mutex 값이 1이라는 것이다. 
    // 따라서 이제 뮤텍스 값을 0으로 만들어 
    // 다른 프로세스(혹은 쓰레드)가 접근하지 못하도록 막아야 한다.
    mutex = 0;
}

void unlock() {
   // 임계 구역에서 나온 프로세스는
   // 다른 프로세스가 접근할 수 있도록 락을 해제한다. 
   mutex = 1;
}

mutex 를 사용해서 ciritical section에 진입할 때 lock을 걸어 다른 프로세스 혹은 스레드가 접근하지 못하도록 하고 ciritical section을 나와 unlock하는 방식이다.

세마포어와의 차이점

  • 세마포어는 뮤텍스가 될 수 있지만 뮤텍스는 세마포어가 될 수 없다.
  • 뮤텍스는 동기화 대상이 1개일 때 사용하고 세마포어는 동기화 대상이 여러 개 일 때 사용한다.

Monitor (모니터)

프로세스 또는 스레드를 동기화하는 방법 중 하나로, 동기화를 위해 구현된 기능 또는 모듈을 뜻하기도 한다.

주로 고급언어에서 이 기능을 지원하며 한번에 하나의 프로세스만 모니터에서 활동하도록 보장해준다.

프레임워크나 라이브러리 그 자체에서 제공되므로 가볍고 빠르다.

하나의 데이터마다 하나의 모니터를 결합할 수 있으며, 모니터는 그것이 결합된 데이터가 동시에 두 개 이상의 스레드에 의해 접근할 수 없도록 막는 잠금 기능을 제공함으로써 동기화를 수행한다는 것이 주된 내용이다.

예시

자바에서 스레드를 동기화하는 방법으로 모니터가 사용된다.
synchronized 메소드가 선언된 객체와 synchronized 블럭에 의해 동기화되는 모든 객체에 고유한 모니터가 결합이 되어 동기화 작업을 수행하게 된다.




Reference
https://velog.io/@conatuseus/OS-세마포어와-뮤텍스
https://hibee.tistory.com/297

0개의 댓글