[OS] Mutex and Semaphore

Hα ყҽσɳɠ·2020년 5월 5일
0

Operating system

목록 보기
10/10
post-thumbnail

지비씨 리눅스 과제할때 급하게 주워담은 지식으로 구현하던 뮤텍스와 세마포어를 드디어 배웠다 둑흔
일단 구현말고 전체적인 개념을 이해하기엔 여기 블로그에 참 좋은 예시로 쉽게 설명이 되어있었다. 보고 흐름을 잡으면 좋을 것 같다.


Mutex

뮤텍스를 이용할 때는 available이라는 변수를 사용할 것인데, 이는 이전에 살펴보았던 lock과는 작동 원리가 반대이다. lock은 false일 때, 임계구역에 들어갈 수 있었는데 available은 true일 때 임계구역에 들어갈 수 있다.
뮤텍스와 관련된 유명한 화장실 예시를 생각해보면 된다. 뮤텍스는 화장실이 1개뿐인 식당과 유사하다. 화장실을 가기 위해 카운터에서 키를 받아가는데, 누군가 이미 화장실에 갔다면 키가 없을 것이고 (available = 0), 이용 가능하다면 키가 있을 것이다. (available = 1) 즉, 뮤텍스는 키에 해당하는 어떤 object가 있으며 이 object를 소유한 프로세스만이 공유 자원에 접근할 수 있다



Semaphore

세마포어를 integer 변수 S라고 할 때, 이 변수는 오직 wait()와 signal()이라는 2가지 atomic operation에 의해서만 엑세스 가능하다.

wait()연산은 공유 자원을 획득하기 위한 진입 영역, signal()연산은 공유 자원을 반납하는 영역에 해당한다. 이 연산들은 반드시 독립적이고 원자적으로 수행되어야 한다.

block & wakeup


세마포어는 여전히 busy-waiting 문제를 가지고 있다. 예를 들어 이진 세마포어의 경우 S가 0일 때 어떤 프로세스는 wait() 연산 내부의 while 문을 돌면서 다른 프로세스가 signal() 연산을 해줄 때까지 기다리며 CPU time을 소모하게 된다.

spinlock이라고도 불리는 busy waiting 문제를 block & wakeup 방식의 세마포어 구현을 통해 해결할 수 있다. 세마포어는 다음과 같은 구조체로 정의된다.

value는 이용 가능한 리소스의 개수, list는 waiting queue를 의미한다.

Wait와 Signal 연산 같은 경우 다음과 같다.

void Wait(semaphore *S) {
  S->value--; // 임계 영역에 들어갈 준비가 되었고 자원을 필요로 한다는 표시
  if (S->value < 0) {
    // 이 프로세스를 S->list에 추가
    block();
  }
}

void Signal(semaphore *S) {
  S->value++; // 작업이 끝나 자원을 반납할테니 다른 프로세스가 가져다쓰라는 표시
  if (S->value <= 0) {
    // S->list로부터 프로세스 P 하나 꺼냄
    wakeup(P);
  }
}

wait 연산이 호출되고 가용 자원이 남아있지 않다면 이 프로세스를 waiting queue에 추가하고 프로세스의 상태를 대기 상태로 전환시킨다. 이후 control이 CPU 스케줄러에게 넘어가고 스케줄러는 다른 프로세스를 선택하여 실행시킨다.


으악 너무 바쁘다 디비 프로젝트 바보 (20.05.06 추가예정이지만 언제 추가할 지 모르겠다 ㅜㅜ 종강 주세여)

profile
𝑯𝒐𝒏𝒆𝒔𝒕𝒚 𝑰𝒏𝒕𝒆𝒈𝒓𝒊𝒕𝒚 𝑬𝒙𝒄𝒆𝒍𝒍𝒆𝒏𝒄𝒆

0개의 댓글