본문 바로가기
Computer Science/Operating System

[Pluto's 컴퓨터 이야기] Mutex와 Semaphore의 차이?

by Dev. Pluto 2022. 2. 28.
반응형

 

안녕하세요 플루토입니다! 이전 시간에는 운영체제 동기화 방식에서 락(SpinLock)방식의 한계와 개선된 방법, 그리고 다른 방식으로 동기화를 했던 Higer-level Synchronization에 대해서 알아보았습니다. 

 

그리고, 대표적인 방법으로 세마포어, 모니터 방식의 동기화를 알아보았는데요

오늘은 세마포어에 대해서 조금 더 자세히 알아보도록 하겠습니다.

 

 

 


 

 

이 글을 읽고난 뒤 여러분은

1. 세마포어의 종류인 Mutex, Counting semaphore에 대해 이해할 수 있습니다.
2. 둘 간의 차이를 이해하고 설명할 수 있습니다.
3. 세마포어의 대표적인 문제점에 대해서 이해할 수 있습니다. 

 

 

 

 

1. 뮤텍스 vs 세마포어?

 

이전 시간에도 알아보았듯 위 두개는 전혀 다른 동기화 방식이 아닙니다. 주요 차이점은 컴퓨터 시스템의 공유자원에 대해 몇 개의 프로세스나 스레드가 접근할 수 있도록 허용하느냐의 차이입니다.

 

이진(Binary)세마포어, 혹은 뮤텍스라 불리는 요소는 한 개의 스레드만 공유자원에 대해 접근을 허용하고, 임계영역을 실행할 수 있도록 하는 방식입니다. 즉 Lock상태와 Unlock상태인 두 개의 방식만 사용한다 하여 이진 세마포어라 생각하시면 됩니다.

 

따라서 하나의 스레드가 임계영역을 실행하는동안 나머지 스레드는 Block당하는 즉 공유자원에 대해 접근을 못하는 것을 보장하며 동기화를 사용합니다.(이 경우에는 세마포어의 Counter변수가 1입니다.)

 

뮤텍스 이외의 세마포어(Counting semaphore이지만 일반적으로 세마포어라 불립니다.)는 공유자원에 대해서 허용 가능한 unit의 수 만큼 프로세스/스레드의 임계영역 실행을 허용합니다. (해당 경우의 Counter변수가 유닛의 수 N으로 초기화 됩니다.)

 

 

 

 

 

한 개의 스레드만 임계영역 실행을 보장하는 Mutex

 

 

 

 

 * Functions in semaphore

 

- wait(): 스레드가 해당 함수를 호출하며 임계영역에 들어가기 위해 준비를 합니다. 이때, 세마포어의 상태가 열려있다면 즉 임계영역에 들어갈 수 있는 상태라면 스레드는 그대로 임계영역을 실행합니다. 

 

그렇지 않고 이미 실행중인 스레드가 존재할 때  세마포어는 닫힘 상태이고, 해당 스레드는 Block당하고 Queue에서 기다리게 됩니다.

해당 함수가 실행되고 임계영역에 들어가면 Counter변수가 한개 감소합니다. (카운터 변수는 임계영역에 들어갈 수 있는 개수라 생각하시면 됩니다. )

 

- signal(): 세마포어를 여는 함수입니다. 

Queue를 확인해서 기다리는 스레드가 존재한다면, 맨 앞의 스레드를 unblock하며 임계영역의 진입을 하용합니다. 

Queue에 기다리는 스레드가 없다면, 해당 함수는 세마포어가 열린 상태라는걸 다음의 wait()함수가 호출이 될 때까지 기다립니다.

해당 함수가 호출되면, Counter변수가 한개 증가합니다. 

 

 

 

두 개 이상의 스레드가 임계영역 실행을 허용하는 (Counting)Semaphore

 

 

2. 두 세마포어의 차이는 무엇이냐?

 

1번 단락에서 설명이 대부분 되었지만 정리하자면 

뮤텍스: 한 개의 프로세스 / 스레드만 임계영역 실행을 할 수 있도록 허용 (카운터 변수의 값이 1로 초기화)
세마포어: 두 개 이상의 프로세스 / 스레드가 임계영역을 실행할 수 있도록 허용(카운터 변수의 값이 N으로 초기화)

 

 

 

3. 세마포어는 완벽한가?

 

결국에는 각 스레드 들이 글로벌변수(Counter)를 공유할 수밖에 없습니다. 동기화가 진행되는 도중에 한번이라도 공유변수를 잘못 변경하게 된다면 세마포어 자체가 무너지게 됩니다.

 

또한 임계영역 내부에서 상호배제와 스케줄링이 동시에 일어나는 문제점도 존재합니다.

 

세마포어는 결국 프로그래머가 작성해야하는 부분이므로 프로그래머의 실수로 인한 세마모퍼의 적절한 사용을 보장할 수 없습니다.

그러므로 DeadLock 이나 Starvation등을 유발하기 쉬워진다.

 

 

 

4. 결론

 

세마포어도 스핀 락 방식에 비해 좀더 개선된 동기화 기법이지만 사람에 의해 구현되어야 하는 부분이기 때문에 어쩔수 없는 결함이 발생입니다. 그래서 이를 프로그래밍 언어 레벨에서 지원하는 모니터 방식의 동기화 방식을 사용합니다. 

 

모니터 동기화 방식은 세마포어를 개선한 방식으로 컴파일러가 런타임에 동기화 코드를 더하고, 이를 강제하는 방식으로 운용됩니다. 

 

반응형