우리네 장

[ 동기화 #2 ] 뮤텍스 본문

OS

[ 동기화 #2 ] 뮤텍스

qpmi1zm29 2023. 12. 27. 01:39

스핀락에서는 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을 획득 하기 위해 시도하다가 대기 상태로 전환하는 것을 말한다.