소피it블로그

[OS] 임계영역 해결 기법 - 뮤텍스(Mutex)와 세마포어(Semaphore) 본문

CS/운영체제

[OS] 임계영역 해결 기법 - 뮤텍스(Mutex)와 세마포어(Semaphore)

sophie_l 2022. 11. 3. 23:49

원문: https://www.guru99.com/mutex-vs-semaphore.html

 

Mutex vs Semaphore – Difference Between Them

Mutex vs Semaphore: The key difference between Mutex and Semaphore is that Mutex is a locking mechanism whereas Semaphore is a signaling mechanism.

www.guru99.com

위의 자료를 번역한 글임을 밝힙니다.

 

직무 면접을 준비하면서 운영체제 개념 복습의 일환으로 뮤텍스와 세마포어의 차이에 대해 여러 블로그 글들을 찾아 읽어보았다. 그런데 블로그마다 말들이 다 조금씩 다르고 봐도 봐도 헷갈려서, 영어로 된 자료를 좀 찾아보기로 했다. 위의 자료가 100% 맞는 것인지는 교차 검증해보진 않았지만 일단 이해하기 쉽게 적혀있어서, 이를 토대로 내가 이해한 바를 번역해보고자 한다.

1. 요약

  • 뮤텍스는 잠금 메커니즘(locking mechanism)인 반면, 세마포어는 신호 메커니즘(signaling mechanism)이다.
  • 뮤텍스는 객체인 반면 세마포어는 integer이다.
  • 뮤텍스는 서브타입이 없는 반면, 세마포어는 카운팅 세마포어와 바이너리 세마포어라는 두 가지 서브 타입을 갖는다.
  • 세마포어는 wait와 signal 오퍼레이션에 의해 상태가 변화하는 반면, 뮤텍스는 리소스를 요청(request)하거나 릴리즈하는 프로세스에 의해서만 상태가 변화한다.
  • 세마포어 값은 wait()와 signal()이라는 오퍼레이션에 의해 변경되는 반면, 뮤텍스의 오퍼레이션은 locked이거나 unlocked이다.

2. 세마포어

세마포어는 음수가 아니며 스레드간에 공유되는 변수를 의미한다. 세마포어는 신호 메커니즘이며, 세마포어에서 대기 중인 스레드는 다른 스레드에 의해 시그널을 받을 수 있다. 세마포어는 1) wait 2) signal이라는 두 가지 원자값의 오퍼레이션만을 사용하여 프로세스 동기 처리를 한다.

세마포어는 자원으로의 접근을 허용하거나 막는데, 이는 어떻게 세팅되었냐에 달려있다.

3. 뮤텍스

뮤텍스는 Mutual Exclusion Object(상호 배제 객체)의 줄임말이다. 뮤텍스는 공유 자원에의 접근을 관리하는데 사용되는 바이너리 세마포어의 세부 타입이다. 뮤텍스는 우선순위 전도 문제를 피하기 위하여 우선순위 상속 메커니즘(priority inheritance mechanism)을 포함한다. 뮤텍스는 현재 우선순위가 더 높은 태스크가 가능한 한 가장 짧은 시간 동안 blocked 상태에 있을 수 있도록 한다. 그러나 우선순위 상속은 우선순위 전도를 해결하지는 못하며, 그 효과를 최소화할 뿐이다.

4. 세마포어의 사용

싱글 버퍼의 경우, 4KB 버퍼를 4개의 1KB 버퍼로 나눌 수 있다. 세마포어는 이 네 가지 버퍼와 연관지을 수 있다. 유저와 생산자로 하여금 동시에 다른 버퍼에서 작업할 수 있도록 한다.

5. 뮤텍스의 사용

뮤텍스는 상호 배제를 제공하며, 키(뮤텍스)를 가지고 작업을 진행할 수 있는 생산자 또는 소비자가 될 수 있다. 생산자가 버퍼를 채우는 동안 유저는 기다려야 하고, 반대 역시 마찬가지이다. 뮤텍스 락에서는 항상 단 하나의 스레드만이 버퍼 전체를 가지고 작업할 수 있다.

6. 세마포어와 뮤텍스의 차이

  세마포어 뮤텍스
메커니즘 신호 메커니즘 잠금 메커니즘
데이터 타입 정수(integer) 변수 객체
변경(modification) wait, signal 오퍼레이션에 의하여 변경 자원을 리퀘스트 또는 릴리즈하는 프로세스에 의해서만 변경
자원 관리 모든 자원이 점유된 상태라면, 프로세스는 wait 오퍼레이션을 실행하는 자원을 필요로 한다. 세마포어의 계수가 0보다 커질 때까지 기다려야 한다. 잠금되어있는 경우 프로세스는 큐 안에서 대기해야 한다. 뮤텍스가 잠금 해제될 때에만 접근 가능하다.
스레드 여러 개의 프로그램 스레드 존재 가능 여러 개의 프로그램 스레드 존재 가능하나 동시에는 불가능
소유권(ownership) 자원을 릴리즈하거나 획득하는 모든 프로세스에 의해 값 변경 가능 락을 획득한 프로세스에 의해서만 객체 락 릴리즈 가능
타입 카운팅 세마포어, 바이너리 세마포어 서브타입 없음
오퍼레이션 wait()와 signal() 오퍼레이션을 통해 세마포어 값이 변경된다. locked 또는 unlocked
자원 점유 모든 자원이 사용중이고 자원을 요구하는 프로세스가 wait() 오퍼레이션을 수행하며 세마포어 계수가 1을 넘길 때까지 자기 자신을 블록할 경우에 점유중이라고 한다. 객체가 이미 잠금되어있는 경우 자원을 요구하는 프로세스는 기다리며, 락이 해제될 때까지 시스템에 의해 큐에 줄세워지게 된다.

7. 뮤텍스와 세마포어에 대한 사실들

  • 단 하나의 태스크만 뮤텍스를 획득할 수 있다. 따라서 뮤텍스를 점유하는 프로세스만이 뮤텍스를 해제할 수 있다.
  • 뮤텍스와 세마포어를 사용하는 이유는 서로 다르지만, 구현의 유사성 때문에 뮤텍스가 바이너리 세마포어라고 불리기도 한다.
  • 뮤텍스와 세마포어에 관해 잘못 알려진 사실: 뮤텍스는 1까지만 셀 수 있고 세마포어는 0부터 N까지 셀 수 있다는 것이 유일한 차이이며 이외에는 거의 비슷하다는 것
  • 바이너리 세마포어와 뮤텍스의 차이에 대한 불분명한 정보들이 많다. 뮤텍스가 바이너리 세마포어라는 사실은 옳지 않다.

8. 세마포어의 장점

  • 임계 영역(critical section)에 하나 이상의 스레드가 접근하는 것을 가능하게 한다.
  • 세마포어는 기계에서 독립적이다(machine-independent).
  • 세마포어는 기계에서 독립된 microkernel 코드로 구현된다.
  • 여러가지 프로세스가 동시에 임계 영역에 접근하는 것을 막는다.
  • 세마포어에는 busy waiting이 있기 때문에, 프로세스 시간과 자원의 낭비가 없다.
  • 자원의 유연한 관리를 가능하게 한다.

9. 뮤텍스의 장점

  • 뮤텍스는 임계 영역에 들어가기 전에 얻어지고 이후에 해제되는 단순한 잠금이다.
  • 임계 영역에는 어떤 순간에도 단 하나의 스레드만이 들어갈 수 있기 때문에 경쟁 상태(race condition)가 없으며, 데이터는 항상 일관되게 유지된다.

10. 세마포어의 단점

  • 세마포어의 가장 큰 한계점은 우선순위 전도이다.
  • 운영체제는 세마포어의 wait과 signal을 위한 모든 요청을 다 추적해야만 한다.
  • 사용이 강제되지 않고 관습에 의해서만 사용된다.
  • 세마포어에서 교착 상태를 피하기 위해서는 wait과 signal 오퍼레이션이 알맞은 순서로 실행되어야만 한다.
  • 세마포어 프로그래밍은 복잡한 메서드이기 때문에 상호 배제가 만족되지 않을 가능성도 있다.
  • modularity의 상실로 이어질 수 있기 때문에 대규모 사용에 적합한 방법이 아니다.
  • 세마포어는 프로그래머의 실수에 영향받기 더 쉽다.
  • 프로그래머의 실수에 의해 교착 상태나 상호 배제의 위반에 이를 수도 있다.

11. 뮤텍스의 단점

  • 스레드가 잠금을 획득한 후 잠에 들거나 대체된 경우 다른 스레드가 진행되지 못할 수 있다. 이 경우 starvation(프로세스가 실행되지 않음) 현상이 일어난다.
  • 락을 획득한 상황 이외의 다른 맥락에서는 잠금되거나 해제될 수 없다.
  • 임계 영역에 단 하나의 스레드만 허용된다.
  • 일반적인 구현을 할 경우 busy waiting 상황이 되어 CPU 시간이 낭비될 수 있다.

여기까지만 봤을 때 아직 완전히 이해가 가지 않는 부분들이 있어서 아래의 자료(+CS 스터디 모 회원님의 설명)를 더 참고하였다.

 

https://github.com/JaeYeopHan/Interview_Question_for_Beginner/tree/master/OS#%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-%EB%8F%99%EA%B8%B0%ED%99%94

 

GitHub - JaeYeopHan/Interview_Question_for_Beginner: Technical-Interview guidelines written for those who started studying progr

:boy: :girl: Technical-Interview guidelines written for those who started studying programming. I wish you all the best. :space_invader: - GitHub - JaeYeopHan/Interview_Question_for_Beginner: Techn...

github.com

 

  • 프로세스에는 프로듀서와 컨슈머가 있는데, 이들이 동시에 변수에 접근하고 조작할 경우 동시성에 문제가 발생할 수 있다.
  • 뮤텍스는 기본적으로 Mutex 'Lock'이다. 임계 영역에 진입할 때 락을 획득하고 나가면서 락을 해제한다. 이를 통해 스레드의 동시 접근을 막는다. 즉, 일종의 열쇠라고 보면 된다.
  • 세마포어는 임계 영역을 해결하기 위한 소프트웨어적인 해결책 중 하나인데(찾아보니 뮤텍스 역시 마찬가지인듯) 그렇기 때문에 프로그래머의 실수에 영향을 받을 수 있다는 것으로 이해된다. 하드웨어적인 해결책과 대비하여 생각해보면 될듯.
  • 세마포어에서 binary와 counting을 나누는 기준은 가용할 수 있는 자원의 개수이다. 카운팅 세마포어의 경우 가용할 수 있는 자원의 개수로 초기화되며 자원을 사용할 경우 세마포어는 감소, 해제할 경우 증가한다.
  • busy waiting: 세마포어의 초기 버전에서 있었던 문제로, 임계 영역에 진입하려는 프로세스는 끊임없이 진입 코드를 반복 실행해야 했으며 그 결과 CPU 시간이 낭비되었다. 이에 대한 해결책으로 임계 영역에 진입하려고 시도하였으나 실패한 프로세스에 대하여 세마포어가 block을 한 후, 임계 영역에 빈 공간이 생길 때 깨우는 방식을 사용한다.

'CS > 운영체제' 카테고리의 다른 글

[OS] 식사하는 철학자들 문제  (0) 2022.11.03