참고 영상
우아한테크의 10분 테코톡 와일더의 Mutex vs Semaphore를 보고 정리해 보았습니다.
아래 영상은 꼭 봐주세요!
https://www.youtube.com/watch?v=oazGbhBCOfU
사전 지식
교착 상태
- 두가지 이상의 작업이 서로 상대방의 작업이 끝나기를 하염없이 기다리는 상태
- 예를 들어 A, B가 존재하고, 각각 연필과 종이를 가져갔다 가정해보자. (점유)
- 그러나 필기를 위해서는 둘다 필요하니 A와 B는 각각 종이와 연필을 요청한다.(대기)
- 당연히 A, B는 필기를 위해 줄 수 없으니 자원을 요청하지만 이 요청을 무한히 대기하는 상태를 교착상태라한다.
- 연필과 종이는 공유자원이라 한다.
- 이런 공유 자원이 속해 있는 공간은 임계영역이라 한다
임계 영역
: 교착 상태가 발생 가능한 영역
조건 4가지 -> 이게 전부 만족해야만 한다 ( == 한 가지라도 만족하지 않으면 교착상태는 일어나지 않는다.)
- 상호 배제(mutual exclusion) : 프로세스 들이 필요로 하는 자원에 대해 배타적인 통제권을 요구한다. => 즉 한놈이 사용중이면 다른 것들은 접근 못하게 통제
- 점유 대기 : 프로세스가 할당된 자원을 가진 상태에서 다른 자원을 기다린다.
- 비선점 : 프로세스가 어떤 자원의 사용을 끝낼 때 까지 뻇어갈 수 없다.
- 순환대기 : 각 프로세스는 다음 프로세스가 요구하는 자원을 가지고 있다.
여기서 상호배제가 이번 이야기에 대한 내용이다.
MUTEX
* mutual과 exclusion의 합성어로 상호배제의 의미가 존재
: 여러 스레드를 실행하는 환경에서 자원에 대한 접근에 제한을 강제하기 위한 동기화 메커니즘
ex)
어떤 한 스레드가 임계영역에서 자원을 사용중이라면 Lock을 해버린다. -> 자원을 점유 중
그럼 다른 스레드가 올 경우 Lock걸려 있으니 이젠 대기를 해야하는데, 이때 두가지 방법이 존재한다
- Mutex는 대기 큐를 생성하고, 임계 영역에 스레드가 있을 경우 다른 스레드가 공유 자원을 사용할려한다면 스레드를 blocking하고 대기큐에 sleep시킨다.
- 반대로 대기 큐에 대기가 아니라 계속 물어보는 방법도 있다. => 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을 해제 가능하다.
그러나 똑같이 꽉 찬다면 다른 스레드들은 대기를 해야한다
여기도 두가지의 방법이 존재한다.
- Sleep-Waiting : 대기 큐에서 sleep하고 있다가, 사용 가능한 자원이 생기면 잠자는 스레드를 꺠운다
- Busy-Waiting : SpinLock과 유사
뮤텍스와 세마포어의 차이점
- 동기화 대상의 개수
Mutex는 동기화 대상이 only 1개일 때 사용
Semaphore는 동기화 대상이 1개 이상일 때 사용 - 세마포어는 뮤텍스가 될 수 있지만 뮤텍스는 세마포어가 될 수 없다.
Mutext는 0,1로 이루어진 이진 상태이므로 Binary Semaphore - Mutex는 자원 소유가능 + 책임을 가지는 반면 Semaphore는 자원 소유가 불가합니다.
- Mutex는 소유하고 있는 스레드 만이 이 Mutex를 해제할 수 있다.
반면, Semaphore는 Semaphore를 소유하지 않는 스레드가 Semaphore를 해제할 수 있다. - Semaphore는 시스템 범위에 걸쳐 있고 파일 시스템 상의 파일로 존재한다.
반면 Mutex는 프로세스의 범위를 가지며 프로세스 종료될 때 자동으로 Clean up됩니다.
댓글