[OS] 세마포오 & 뮤텍스
업데이트:
세마포오(Semaphore) & 뮤텍스(Mutex)
공유된 자원에 여러 프로세스가 동시에 접근하면서 문제가 발생할 수 있다. 이때 공유된 자원의 데이터는 한 번에 하나의 프로세스만 접근할 수 있도록 제한을 둬야 한다.
이를 위해 나온 것이 바로 '세마포오'
와 '뮤텍스'
이다.
세마포오 : 멀티 프로그래밍 환경에서 공유 자원에 대한 접근을 제한하는 방법
뮤텍스 : 임계 구역을 가진 스레드들의 실행시간을 서로 겹치지 않고 각각 단독으로 실행되게 하는 기술 (Lock, Unlock 을 이용해서 한번에 하나의 스레드만 사용되도록 )
세마포오와 뮤텍스의 대한 설명을 들어가기 전에 알아야 할 개념은 임계구역(Critical Section)
이다.
Critical Section : 여러 프로세스가 데이터를 공유하며 수행될 때, 각 프로세스에서 공유 데이터를 접근하는 프로그램 코드 부분
공유 데이터를 여러 프로세스가 동시에 접근할 때 잘못된 결과를 만들 수 있기 때문에, 한 프로세스가 임계 구역을 수행할 떄는 다른 프로세스가 접근하지 못하도록 해야 한다.
세마포오
세마포오에서는 다음과 같은 개념들이 포함된다.
P (wait)
: 임계 구역 들어가기 전에 수행(프로세스 진입 여부를 자원의 개수(S)를 통해 결정)
V (signal)
: 임계 구역에서 나올 떄 수행(자원 반납 알림, 대기 중인 프로세스를 깨우는 신호)
S
: 동시 접근할 수 있는 프로세스(스레드) 갯수라고 생각하면 된다. 따라서 이 값이 1이면 Mutex랑 같은 효과를 낼 수 있다(이진세마포오
). 그리고 S는 전역변수
이다.
이러한 P와 V를 구현해보면 다음과 같다.
P(S){ // -> 잔다는 개념
while(S <= 0){ // S가 0 이하면 동작할 수 없기 때문에
; // busy waiting -> S가 0이 될때까지 무한 루프
}
S--;
}
V(S){
S++; // 자원을 반납하면서 동작할 수있는 S카운트 값을 증가시켜 다른 프로세스(스레드)가 동작하도록 할 수 있다. -> 깨운다는 개념
}
이를 통해, 한 프로세스가 P 혹은 V를 수행하고 있는 동안 프로세스가 인터럽트 당하지 않게 된다. P와 V를 사용하여 임계 구역에 대한 상호배제 구현이 가능하게 되었다.
예시
- 먼저 도착한 A가 P(S)를 실행하여 S값을 0으로 만들고 임계구역으로 들어감
- 그 뒤에 도착한 B가 P(S)를 실행하지만 S가 0이기에 대기상태
- A가 임계구역 수행을 마치고 V(S)를 실행하면 S는 다시 ++됨
- B는 이제 P(S) 무한루프에서 빠져나올 수 있게 되고 임계구역 들어가서 수행
뮤텍스
뮤텍스는 임계구역 동시 접근을 통해 문제가 생기는 것을 막기 위해 Lock이란 개념을 사용한다.
Lock
: 현재 임계 구역에 들어갈 권한을 얻어옴(만약 다른 프로세스/스레드가 임계 구역 수행 중이면 종료할 때까지 대기)
Unlock
: 현재 임계 구역을 모두 사용했음을 알림(대기 중인 다른 프로세스/스레드가 임계 구역에 진입할 수 있음)
뮤텍스는 S값이 0,1인 이진 세마포오
라고 부르기도 함
while(1){
acquire block
critical section
release block
remainder section
}
acquire(){
while(!available){ // 현재 어떤 프로세스가 점유하고 있다면 무한루프
; // busy waiting
}
available = false;
}
release(){
available = true;
}
예시(OS 공룡책 참조)
#include stdio.h
#include pthread.h
int sum 0; // a shared variable
pthread_mutex_t mutex;
void *counter (void *param)
{
int k;
for(k = 0; k < 10000; k++){ // 10000번 스레드
// entry section
pthread_mutex_lock(&mutex); // mutex lock
// critical section
sum++;
// exit section
pthread_mutex_unlock(&mutex);
// remainder section
pthread_exit(0)
}
}
int main
{
pthread_t tid1 tid2;
pthread_mutex_init(&mutex, NULL);
pthread_create(&tid1, NULL, counter, NULL);
pthread_create(&tid2, NULL, counter, NULL);
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
printf("sum == %d\n ",sum);
}
Summary
Critical Section이라는 공유 공간에 여러 프로세스들이 동시 접근하게 될 때 동기화란 개념이 들어가지 않는다면 문제가 생길 것이다. 그러한 것들을 해결하기 위한 동기화 방법 중 세마포오와 뮤텍스에 대해 알아 보았습니다.
각각 세부적인 내용을 깊게 들어간다면 너무 복잡해지기에 나중에 시간이 된다면 정리하겠습니다.
댓글남기기