Mutex
Lock과 Unlock이라는 설정 값으로 임계영역에 대한 실행가능 여부를 결정하여 공유자원에 대한 접근의 질서(Synchronization)를 정한다.
Lock을 걸어놓은 Thread만이 공유자원을 Access할 수 있으며 다른 Thread는 Unlock이 될때까지 공유자원을 Access할 수 없다는 방식이다.
1. Mutex 동작방식
♦ Thread는 Unlock인 상태에서만 임계영역에 진입 가능하다.
♦ 임계영역에 진입할 수 있는 경우에는 먼저 Lock을 걸어준다.
♦ Lock을 걸어준 Thread만이 공유자원을 access 할 수 있다.
♦ 임계영역에 빠져 나올 때에는 Lock 상태를 Unlock으로 전환 해준다.
♦ 임계영역에 있는 Thread만이 Unlock을 할 수 있다.
⊗ Unlock인 상태에서 임계영역에 진입하고자 할 경우에는 최대한 빨리(atomic operation) Lock을 걸어준다.
2. Mutex 구현초안
뮤텍스는 Busy-Waiting 이라는 방식을 사용하여 가장 단순하게 구현되어 질 수 있다.
아래의 예에서 전역변수 key가 Lock 과 Unlock의 상태를 표시하고 있다.
global int key=1; | // 해제 또는 허용(unlock) → Key=1, 배제 또는 불허(lock)→ key=0, |
공유자원을 사용하는 momo 쓰레드 구현 | 공유자원을 사용하는 toto 쓰레드 구현 |
void momo(void){ while(key=1) key=0;
momo의 공유자원엑세스(임계영역);
key=1;
기타 다른 할 일들 처리; } |
void toto(void){ while((key=1) key=0; //mutex lock 구현 //해제상태가 될때까지 뺑뺑이 돈다. 기회를 얻으면 lock 시키고 임계영역 진입. toto의 공유자원엑세스(임계영역);
key=1; //mutex unlock 구현 // 일을 끝마치고 다른 쓰레드가 자신의 임계영역을 실행할 수 있도록 기회를 준다 기타 다른 할 일들 처리; } |
3. Mutex 구현보완
Busy Waiting 방식은 만일 momo 가 비교적 장시간 동안 Unlock을 해주지 않으면, toto는 그 동안 계속 그 자리에서 뺑뺑이만 돌고 있게 된다.
RTOS 시스템은 모든 쓰레드들이 시간을 긴요하게 나누어 쓰고 있는데 toto가 Running 상태에서 뺑뺑이만 돌면서 시스템 시간을 허비하고 있는 것이다.
따라서 RTOS 시스템에서는, 시스템마다 차이는 있겠지만, 다음과 같은 기능을 추가하여 Busy Waiting 방식을 보완하여 구현되어 있다.
함수
|
기능설명 |
mutex_lock
|
Locks the mutex, blocks if the mutex is not available mutex_lock을 호출한 쓰레드가 베제되었을 경우 이 쓰레드는 Block(대기상태의 일종)로 빠진다. |
mutex_try_lock
|
Tries to lock the mutex, returns if the mutex is not available mutex_try+lock을 호출한 쓰레드가 베제되었을 경우 이 쓰레드는 실행을 종료하고 대기상태로 빠진다. |
mutex_unlock
|
Unlocks the mutex 베제되어 대기상태에 있는 쓰레드들에게 뮤텍스가 해제되었다는 신호를 보내 준비상태로 천이되도록 한다. |
Pseudo 코드구현
Thread가 공유자원을 사용할 수 없을 때 무작정 기다리지 않고 대기상태로 빠지도록 만든다.
결과로, 실시간적으로 일을 처리 해야하는 다른 Thread들이 일을 처리할 수 있는 기회(시간)을 더 많이 할당 받을 수 있게 될 것이다.
mutex_t mutex=1; | |
공유자원을 액세스하는 momo thread 구현 | 공유자원을 액세스하는 momo thread 구현 |
void momo(void){ mutex_lock(&mutex); 또는 mutex_try_lock(&mutex);
momo의 공유자원엑세스(임계영역); mutex_unlock(&mutex);
기타 할 일들을 처리한다; } |
void toto(void){ mutex_lock(&mutex); 또는 mutex_try_lock(&mutex); // Unlock까지 여기서 무작정 뺑뺑이 돌지 않는다. toto의 공유자원엑세스(임계영역); mutex_unlock(&mutex); //Unlock을 해주고 대기 중인 Thread가 대기상태에서 빠져 나오도록 조치한다. 기타 할 일들을 처리한다; } |