페이지 선택
Generic selectors
Exact matches only
Search in title
Search in content
Search in pages

Semaphore

공유자원의 개수가 여러개 있을때, 그 수만큼의 thread만이 임계영역에 진입하여 있을 수 있도록 제한하는 방식이다.

현재 사용 가능한 공유자원의 개수는 int x와 같은 정수형 변수로 관리하는데 이 변수 x를 특별히 Semaphore라 부른다.

Semaphore는 또한 Smaphore를 사용해서 공유자원문제를 해결하는 방법에 대한 의미를 포함하기도 한다.

⊗ 공유자원의 개수가 1개일때 Binary Semaphore라 하며, 2개 이상인 경우에 Count Semaphore라 한다.

 

 

 

1. Semaphore 동작방식

♦ Thread는 Semaphore 값이 0 보다 큰 경우에만 임계영역으로 진입 할 수 있다.

♦ 임계영역에 진입할 수 있는 경우에는 먼저 현재의 Semaphore 값을 1 감소시킨다.

♦ 공유자원을 Access하고, 임계영역을 빠져 나올 때에는 Semaphore 값을 1 증가 시킨다. → 이를 Signalling이라 한다.

임계영역에 있지 않은 Thread도 Signaling은 줄 수 있다.

 

⊗ Semaphore 값을 변결할 때에는 최대한 빠르게(atomic operation) 변경할 수 있도록 한다.

 

 

 

2.  Semaphore 구현초안

세마포어의 구현도 뮤텍스에서와 마찬가지로 Busy-Waiting 방식으로 가장 단순하게 구현되어 질 수 있다.

아래에서 변수 count가 Semaphore 이다. 즉 현재 임계영역에 입장 가능한 쓰레드의 수를 나타내고 있으며,

Thread는 count>0일 때만 임계영역으로 진입할 수 있으다.

 

global int count=3; // 공유자원 최대개수=3, 즉 count=0 진입불가 신호, count>0  진입가능 신호
공유자원을 사용하는 momo thread 구현 공유자원을 사용하는 momo thread 구현

void momo(void ) {

while(count>0) count–;      

 

momo의 공유자원 액세스(임계영역);

count++;   

 

기타 다른 할일들 실행;            

}

void toto(void ) {

while(count>0) count–;  //세마포어 wait 구현

// 공유자원의 사용권이 1장 이상일 때 까지 무한 대기한다.

toto의 공유자원 액세스(임계영역);

count=count++;  //세마포어 signal 구현

// 공유자원의 사용권을 1 중가시켜, 다른 쓰레드가 임계영역에 진입할 수 있도록 신호를 보낸다.

기타 다른 할일들 실행;

}

 

 

 

 

 

3.  Semaphore 구현보완

Busy-Waiting 방식에서는 모든 자원이 사용 중일 때  새로 자원을 사용하려는 Thread는 그 자리에서 계속 뺑뺑이만 돌고 있을 것이다.

RTOS는 시간이 금인데 하는 일 없이 뺑뺑이만 돌고 있는 Thread에게도 시간을 할당 해주어야 하니 미칠 노릇이다.

따라서 RTOS 시스템에서는, 시스템마다 차이는 있겠지만, 다음과 같은 기능을 추가하여 Busy Waiting 방식을 보완하여 구현되어 있다.

 

기능추가 기능설명

type struct{

int count;

struct thread *waiting_queue;

}sem;

기존 Count(semaphore)를 구조체 sem(semaphore)으로 확장해서,

→Thread 리스트를 기록할 Queue 를 추가하였다.

 

wait(sem){

sem.count–;

if(sem.count<0) block();

}

기존  wait에 thread가 뺑뺑이 돌 상황이라면 block/sleep/suspend 상태로 천이 될 수 있도록 기능을 추가한다.

→ 뺑뺑이 돌 상황의 쓰레드는 자신을 block 상태로 천이 시킨다, 해당 thread는 waiting_queue에 넣어진다.

signal(sem){

sem.count++;

if(sem.count<=0) wakeup();

}

기존 signal에 wakeup()을 추가하였다.

→ 대기상태의 Thread 중 하나를 Ready 상태로 복귀시킨다. 해당 thread는 waiting_queue에서 빠져나온다.

 

 

Pseudo 코드구현

다음과 같이 구현하여 Thread가 공유자원을 사용할 수 없을 때 무작정 기다리지 않고 대기상태로 빠지도록 만든다.

결과로, 실시간적으로 일을 처리 해야하는 다른 Thread들이 일을 처리할 수 있는 기회(시간)을 더 많이 할당 받을 수 있게 될 것이다.

공유자원을 access 하는 momo thread 공유자원을 access 하는 toto thread

void momo(void ) {

wait(sem);     

 

momo 쓰레드의 공유자원 액세스(임계영역);

 

signal(sem);        

기타 다은 할일들 처리;

}

void toto(void ) {

wait(sem);   

 

toto 쓰레드의 공유자원 액세스(임계영역);

 

signal(sem);   

기타 다른 할일들 처리;

}

 

 

Adsense

EMW3070

Viewed Page List