CS

세마포어(Semaphore)

남생이야 2024. 5. 21. 04:21

 정의   

  세마포어는 공유자원이 하나 이상일 때 처리하는 동기화 방법이다. 

 세마포어는 교착 상태에 대한 해법으로 원자적 함수로 제어되는 정수 변수로 병렬 프로그래밍 환경에서 공유자원에 대한 접근 제어를 하는 방법 1개의 공유되는 자원에 제한된 개수의  프로세스 혹은 쓰레드가 접근할 수 있도록 한다. 

원자성 

여러 쓰레드가 존재할 때, 특정 시점에서 어떤 함수를 2개 이상 쓰레드가 동시에 호출하지 못하는 성질을 말한다. 
이러한 성질을 보장한 함수를 원자적 함수라고 한다. 

 

구성 

 

  세마포어는 두 가지 형태를 갖는다. 첫 번째로 카 카운팅 세마포어(Counting Semaphore)와 바이너리 세마포어(Binary Semaphore)가 있다. 

 카운팅 세마포어는 정수 값을 가지며 여러 개의 자원을 관리할 수 있다. 

 바이너리 세마포어는 0 또는 1의 값을 가지며, 뮤텍스와 유사하게 동작한다.

 세마포어는 두 가지의 주요 연산을 통해 동작하는데 ' Wait '연산과 ' Signal '연산이다. 

 

Wait 연산

 p 연산이라고도 불리며, 세마포어 변수의 값을 감소시키고 0이라면 작업 중인 프로세스나 스레드를 대기 상태로 만드는 역할을 한다. 

Wait  연산의 동작 순서는 다음과 같다.

 1) 세마포어의 값을 확인한다.

 2) 값이 0보다 크다면 세마포어 값을 1감소시키고 작업을 계속 수행한다.

 3) 값이 0이 되면 임계구역에 더이상 접근을 허용하지 않게 하기 위해 대기 시킨다. 

 

Signal 연산

 V연산이라고도 불리며 세마포어 변수의 값을 증가시키고 프로세스나 쓰레드의 대기 상태를 해제하는 역할을 한다.

 동작 순서는 다음과 같다. 

 1) 세마포어 값을 1 증가한다.

 2) 대기 중인 프로세스나 쓰레드를 깨운다. 

 

 

적용

  • Busy Waiting 
 P(S) {
     while S <=0; // 아무것도 하지 않음 (반복문)
     S--;
 }

 V(S) {
     S++;
 }

 무한루프를 이용하여 임계구역에 락을 거는 것을 'Spin Lock'이라고 한다. Busy Wait 알고리즘에서 P 연산을 수행 시 while로 spin lock 걸어 다른 프로세스나 쓰레드가 접근하는 것을 막는다. 

- 임계 구역에 들어갈 수 있을 때까지 빈 반복문을 수행시켜 처리하는 방법으로 단일처리 프로세스에선 효율이 떨어진다. 더불어 대기 중인 프로세스들 중 어느 것을 먼저 임계 구역에 진입시킬지 결정할 수 없다는 단점이 있다. 

 

  • Block-Wake Up 
 P(S) {
     S--;
     if S < 0
         // 이 프로세스를 재움 큐에 추가 (잠 듦)
 }

 V(S) {
     S++;
     if S <= 0
         // 재움 큐로부터 프로세스를 제거 (깨어남)
 }

 - Busy Wating 방법을 보완한 방법으로 대기 큐 (Waiting Queue)를 활용하여 프로세스를 재우는 방식이다. 

 

 

 

 

참고

https://ko.wikipedia.org/wiki/%EC%84%B8%EB%A7%88%ED%8F%AC%EC%96%B4

https://velog.io/@octo__/%EC%84%B8%EB%A7%88%ED%8F%AC%EC%96%B4Semaphore