우리네 장
[ 동기화 #2 ] 뮤텍스 본문
스핀락에서는 lock 해제를 확인하는 스레드 혹은 프로세스 ( T/P ) 들을 실행하느라 cpu에 낭비가 발생한다고 하였다.
뮤텍스는 이를 보완하여, entry queue를 사용해 lock을 점유하고자 하는 T/P들을 wait 상태로 변경하고, cpu가 다른 T/P를 처리할 수 있도록 하였다.
세마포어를 소개하면서 말하겠지만, 뮤텍스는 lock을 획득한 T/P만 lock을 해제 할 수 있다.
public class Mutex {
private volatile int lock = 0;
private volatile int value = 0;
//lock도 일종의 여러개의 T/P가 공유하는 공유자원 이므로, 임계영역으로 보호해주기 위해 추가된 변수이다.
//value를 사용하게 되면 lock과 unlock이 동시에 발생하는 경우를 막아준다.
public void lock() {
//acquire lock
while ( test_and_set ( &value ) );
if ( lock == 1 ) {
//스레드를 entry queue에 삽입
} else {
lock = 1;
}
value = 0;
}
public void unlock() {
//release lock
while ( test_and_set (&value) );
if ( queue에 하나라도 대기 중이라면 ) {
//해당 스레드 실행
}else {
lock = 0; //lock을 초기화
}
value = 0;
}
}
스핀락 보다는 뮤텍스를 더 많이 사용하는 추세인데, 스핀락이 더 효율적인 경우가 있다.
뮤텍스는 다음 스레드 혹은 프로세스 ( T/P )를 실행하기 위해서, Dequeue의 과정을 거치는 경우가 많다.
이후 필요할 경우 커널모드로 진입하여 컨텍스트 스위칭 작업도 해주어야 하는데,
만약 임계 영역의 코드가 매우 짧거나 연산이 단순하여 < 위 일련의 과정보다 처리 속도가 적게 들경우,
스핀락을 사용하는 것이 더 유리할 수 있다.
그러나 이는 멀티 코어의 경우일 때 해당하는 이야기이고, 싱글 코어일 경우에는 스핀락을 사용하더라도 반드시 컨텍스트 스위칭 작업이 필요하게 되므로 효과를 발휘할 수 없다.
즉, 멀티 코어 환경에서 임계영역의 코드가 매우 짧고 단순한 연산일 경우, 뮤텍스보다 스핀락이 유리할 수 있다.
최근에는 뮤텍스 + 스핀락 = 하이브리드 뮤텍스를 사용하는 추세라고 한다.
하이브리드 뮤텍스 ?
- lock 획득을 대기 중인 스레드를 바로 entry queue에 넣고 wait 상태로 전환하는 것이 아니라,
몇 번 lock을 획득 하기 위해 시도하다가 대기 상태로 전환하는 것을 말한다.
'OS' 카테고리의 다른 글
가시성 feat.volatile (0) | 2023.12.27 |
---|---|
[ 동기화 #3 ] 세마포어 (1) | 2023.12.27 |
[ 동기화 #1 ] 스핀락 (0) | 2023.12.27 |
[ OS ] 동기화 기법 소개3_Thread.join() 분석해보자! (1) | 2022.10.02 |
[ OS ] 동기화 기법 소개2_모니터! ( monitor! ) (1) | 2022.09.16 |