본문 바로가기
CS/OS

세마포어 vs 뮤텍스

by hyohyohyo 2023. 4. 3.
728x90

참고 영상

우아한테크의 10분 테코톡 와일더의 Mutex  vs Semaphore를 보고 정리해 보았습니다.

아래 영상은 꼭 봐주세요!

https://www.youtube.com/watch?v=oazGbhBCOfU 

사전 지식

교착 상태

  • 두가지 이상의 작업이 서로 상대방의 작업이 끝나기를 하염없이 기다리는 상태
  • 예를 들어 A, B가 존재하고, 각각 연필과 종이를 가져갔다 가정해보자. (점유)
  • 그러나 필기를 위해서는 둘다 필요하니 A와 B는 각각 종이와 연필을 요청한다.(대기)
  • 당연히 A, B는 필기를 위해 줄 수 없으니 자원을 요청하지만 이 요청을 무한히 대기하는 상태를 교착상태라한다.
  • 연필과 종이는 공유자원이라 한다.
  • 이런 공유 자원이 속해 있는 공간은 임계영역이라 한다

임계 영역

: 교착 상태가 발생 가능한 영역

조건 4가지 -> 이게 전부 만족해야만 한다 ( == 한 가지라도 만족하지 않으면 교착상태는 일어나지 않는다.)

  1. 상호 배제(mutual exclusion) : 프로세스 들이 필요로 하는 자원에 대해 배타적인 통제권을 요구한다. => 즉 한놈이 사용중이면 다른 것들은 접근 못하게 통제
  2. 점유 대기 : 프로세스가 할당된 자원을 가진 상태에서 다른 자원을 기다린다.
  3. 비선점 : 프로세스가 어떤 자원의 사용을 끝낼 때 까지 뻇어갈 수 없다.
  4. 순환대기 : 각 프로세스는 다음 프로세스가 요구하는 자원을 가지고 있다.

여기서 상호배제가 이번 이야기에 대한 내용이다.

 

MUTEX

* mutual과 exclusion의 합성어로 상호배제의 의미가 존재

: 여러 스레드를 실행하는 환경에서 자원에 대한 접근에 제한을 강제하기 위한 동기화 메커니즘

ex)

어떤 한 스레드가 임계영역에서 자원을 사용중이라면 Lock을 해버린다. -> 자원을 점유 중

그럼 다른 스레드가 올 경우 Lock걸려 있으니 이젠 대기를 해야하는데, 이때 두가지 방법이 존재한다

  1. Mutex는 대기 큐를 생성하고, 임계 영역에 스레드가 있을 경우 다른 스레드가 공유 자원을 사용할려한다면 스레드를 blocking하고 대기큐에 sleep시킨다.
  2. 반대로 대기 큐에 대기가 아니라 계속 물어보는 방법도 있다. => SpinLock 이렇게 기다리고는 있지만 쉬지 않고 계속해서 묻는 행위를  Busy Waiting 이라 한다.
    • 다만 이런 경우 다른 작업을 못하니 비효율이 나온다

어찌되었던 이제 안의 스레드가 작업을 다 마치고나면 Lock이 해제되고, 이제 다른 스레드가 진입 가능하게 된다. 

== Lock을 건 스레드 만이 Lock을 해제 가능하다.

SpinLock

* 기본적으로 뮤텍스와 유사하지만 대기 큐가 없고, 블락 하지 않으므로 Mutex-Nonblocking모델이라 볼 수 있다.

  • 언제쓰면 좋을까?
    • 컨텍스트 스위칭 시간이 더 짧은가? => 대기실까지 가는 것보다 기다리는게 더 빠른 경우
    • 멀티코어 프로세스인가? => 질문 대답에 응답할 사람이 더 있는 경우

세마포어

: 멀티프로그래밍 환경에서 다수의 프로세스나 스레드의 여러개의 공유 자원에 대한 접근을 제한하는 방법

* 뮤텍스랑은 다르게 여러 스레드가 동시에 접근 가능하다.

ex) 식당에 자리가 한개가 아닌 여러개가 있다 가정

예를 들어 손님을 3명까지 올 수 있다 하자

그렇게 되어 손님이 와 좌석이 다 점유되면 남은 좌석의 개수는 0(카운터) -> 세마포어 변수이 된다.

=> 그럼 언제 이 좌석 수를 갱신하는게 맞을 까? => 식당에 진입 하는 순간 P(wait), 나가는 순간 V(signal)라고 하자

(P, V는 atomic operation이라 하자)

 

그래서 세마포어 변수를 통해 wait, signal을 관리 할 수 있다. 세마포어 변수는 0 이상의 정수형 변수를 가진다.

계수 세마포어로도 사용이 가능한데, 공유 자원의 수가 1개라면 이진 세마포어로 뮤텍스처럼 사용 가능하다.

제일 중요한건 Lock을 걸지 않은 스레드도 Signal을 보내 Lock을 해제 가능하다.

 

그러나 똑같이 꽉 찬다면 다른 스레드들은 대기를 해야한다

여기도 두가지의 방법이 존재한다.

  1. Sleep-Waiting : 대기 큐에서 sleep하고 있다가, 사용 가능한 자원이 생기면 잠자는 스레드를 꺠운다
  2. Busy-Waiting : SpinLock과 유사

뮤텍스와 세마포어의 차이점

  1. 동기화 대상의 개수
    Mutex는 동기화 대상이 only 1개일 때 사용
    Semaphore는 동기화 대상이 1개 이상일 때 사용
  2. 세마포어는 뮤텍스가 될 수 있지만 뮤텍스는 세마포어가 될 수 없다.
    Mutext는 0,1로 이루어진 이진 상태이므로 Binary Semaphore
  3. Mutex는 자원 소유가능 + 책임을 가지는 반면 Semaphore는 자원 소유가 불가합니다.
  4. Mutex는 소유하고 있는 스레드 만이 이 Mutex를 해제할 수 있다.
    반면, Semaphore는 Semaphore를 소유하지 않는 스레드가 Semaphore를 해제할 수 있다.
  5. Semaphore는 시스템 범위에 걸쳐 있고 파일 시스템 상의 파일로 존재한다.
    반면 Mutex는 프로세스의 범위를 가지며 프로세스 종료될 때 자동으로 Clean up됩니다.

'CS > OS' 카테고리의 다른 글

OS공부  (0) 2023.04.27

댓글