25 Aug 2020
뮤텍스(mutex) 세마포어(semaphore)
임계영역
- 다중 프로그래밍에서 여러 프로세스가 데이터를 공유하면서 수행할때 각 프로세스에서 공유 데이터를 엑세스하는 코드 부분이다.
뮤텍스와 세마포어의 차이
-
뮤텍스
-
공유된 자원의 데이터를 여러 스레드가 접근하는 것을 막는것
-
상호배제라고도 하며 임계영역을 가진 스레드의 Running time이 서로 겹치지 않도록 각각 단독으로 실행하게 하는 방법이다.
-
다중 스레드들의 공유 리소스에 대한 접근을 조율하기 위해 synchronized(java),lock(c)을 사용한다.
-
뮤텍스 객체를 두 스레드가 동시에 사용할 수 없다.
-
세마포어
-
공유된 자원의 데이터를 여러 프로세스가 접근하는 것을 막는 것
-
리소스 상태를 나타내는 간단한 카운터로 생각할 수 있다.
-
운영체제 또는 커널의 한 지정된 저장장치 내의 값이다.
-
일반적으로 비교적 긴 시간을 확보하는 리소스에 대해 이용한다.
-
유닉스 시스템 프로그래밍에서 세마포어는 운영체제의 리소스를 경쟁적으로 사용한는 다중 프로세스에서 동기화시키는 기술이다.
-
공유 리소스에 접근할 수 있는 프로세스의 최대 허용치만큼 동시에 사용자가 접근하여 사용할 수 있다.
-
각 프로세스는 세마포어 값을 확인하고 변경할 수 있다.
-
사용 중이지 않는 자원의 경우 그 프로세스가 즉시 자원을 사용할 수 있다.
-
이미 다른 프로세스에 의해 사용 중이라는 사실을 알게되면 재시도하기 전에 일정 시간을 기다려야 한다.
-
세마포어를 사용하는 프로세스는 값을 확인하고, 자원을 사용하는 동안에는 그 값을 변경하여 다른 세마포어 사용자들을 기다리도록 해야 한다.
-
세마포어는 이진수를 사용하거나 추가적인 값을 가질 수도 있다.
-
차이점
-
동기화 대상의 개수
-
Mutex는 동기화 대상이 오직 하나일때, 세마포어는 동기화 대상이 하나 이상일때 사용한다.
-
세마포어는 뮤텍스가 될 수 있지만 반대는 안된다.
-
뮤텍스는 상태가 0,1두 개 뿐인 binary semaphore
-
뮤텍스의 경우 뮤텍스를 소유하고 있는 스레드가 뮤텍스를 해제할 수 있다. 하지만 세마포어는 이러한 세마포어를 소유하지 않는 스레드가 세마포어를 해제할 수 있다.
-
세마포어는 시스템 범위에 걸쳐있고 파일 시스템상의 파일 형태로 존재하는 반면 뮤텍스는 프로세스 범위를 가지며 프로세스가 종료될 때 자동으로 clean up 된다.
세마포어(semaphore)
- 프로세스간 메시지를 전송하거나, 공유메모리를 통해 특정 데이터를 공유하게 되는 경우 문제가 발생할 수 있다. 즉, 공유된 자원에 여러 개의 프로세스가 동시에 접근하면서 문제가 발생되는 것으로 공유된 자원은 한 번에 하나의 프로세스만 접근할 수 있도록 제한 해야 하는데 이를 위한 것이 세마포어이다.
세마포어 동작원리
세마포어는 정수 값을 가지는 변수로 볼 수 있다. 그 정수 값은 접근할 수 있는 최대 허용치 만큼 동시에 사용자 접근을 할 수 있게 한다.
-
semWait : 세마포어 값을 감소시킨다. 만일 값이 음수가 되면 semWait을 호출한 프로세스는 블록된다. 음수가 아니면, 프로세스는 계속 수행될 수 있다.
-
semSignal : 세마포어 값을 증가시킨다. 만약 값이 양수가 아니면 semWait연산에 의해 블록된 프로세스들을 깨운다.
struct Semaphore{
int count;
};
void semWait(Semaphore s){
s.count--;
if(s.count<0){
//요청한 프로세스를 블록 상태로 전이
//여기로 왔다는 건 현재 프로세스(혹은 쓰레드가) 공유자원에 접근할 수 없다는 것을 의미한다.
}
}
void semSignal(Semaphore s){
s.count++;
if(s.count<=0){
//count가 0보다 작거나 같다는 것은 대기하고 있는 프로세스(또는 쓰레드)가 존재한다는 것을 의미한다.
}
}
const int n=프로세스 개수
Semaphore s=1;
void p(int i){
while(true){
semWait(s)
// 임계영역
semSignal(s);
}
}
뮤텍스
뮤텍스는 세마포어와 마찬가지로 병행 처리를 위한 동기화 기법 중 하나로 이진 세마포어와 같이 초기값을 1과 0으로 가진다. 임계영역에 들어갈때 lock을 걸어 다른 프로세스(또는 쓰레드)가 접근하지 못하도록 하고 임계영역에서 나와 해당 락을 unlock한다.
mutex=1;
void lock(){
while(mutex!=1){
//mutex값이 1이 될 때까지 기다린다.
}
// mutex값이 1이 됬다-> mutex값을 0으로 만들어
// 다른 프로세스(혹은 쓰레드)가 접근하지 못하게 한다.
mutex=0;
}
void unlock(){
//임계구역에서 나온 프로세스는 다른 프로세스가 접근할 수 있도록 락을 해제한다.
mutex=1;
}
뮤텍스와 세마포어의 차이
-
세마포어는 공유자원에 세마포어의 변수만큼의 프로세스(또는 쓰레드)가 접근할 수 있다. 반면에 뮤텍스는 오직 1개만의 프로세스(또는 쓰레드)만 접근할 수 있다.
-
현재 수행중인 프로세스가 아닌 다른 프로세스가 세마포어를 해제할 수 있다. 하지만 뮤텍스는 lock을 획득한 프로세스가 반드시 그 lock을 해제해야 한다.