뮤텍스와 세마포어

최창효·2022년 11월 25일
0

뮤텍스

뮤텍스란 하나의 프로세스가 임계 영역 내에 있다면 이 프로세스의 동작이 끝날 때가지 다른 프로세스가 임계 영역에 들어올 수 없도록 제한하는 알고리즘입니다.

공유 자원에 여러 스레드(프로세스)가 접근을 시도할 때 자원을 사용하는 스레드가 없다면 접근을 허용합니다. 접근을 허락 받은 스레드는 을 걸고 자원을 활용합니다. 이때 다른 스레드의 접근을 막는 락이 바로 Mutex Lock입니다. 락이 걸린 상태에서 다른 스레드는 자원을 점유중인 스레드의 작업이 종료될 때 까지 해당 자원에 접근할 수 없습니다.

Spin Lock(Busy Waiting)은 자신이 원하는 자원의 이 해제될 때 까지 while문을 통해 지속적으로 자원에 접근을 시도합니다.

반면에 뮤텍스는 당장 자원을 사용하지 못할 때 큐에서 sleep 상태로 대기하게 됩니다. 자원을 사용한 스레드는 자원사용을 종료한 뒤 큐에서 대기중인 스레드를 깨우고 나갑니다. 이 때 sleep상태의 스레드가 다시 가동되기 위한 Context Switching비용이 발생합니다.

만약 공유 자원을 사용하는데 소요되는 시간(대기시간)보다 Context Switching비용이 더 크다면 Mutex보다 SpinLock이 더 좋습니다. 멀티코어 환경에서는 이처럼 SpinLock이 더 좋은 상황이 발생할 수 있지만 싱글코어 환경에서는 항상 Mutex가 더 좋습니다. 그 이유는 SpinLock에서 락이 해제됐는지 확인하는 작업을 할 때마다 공유 자원에 접근 중인 스레드의 CPU를 뺏어와야 하기 때문입니다. (방이 비었는지 노크할때마다 안에 있는 사람이 작업을 진행하지 못하게 됩니다.)

세마포어

세마포어는 뮤텍스의 공유자원이 여러 개로 확장된 개념입니다. 세마포어는 count변수대기 큐를 가지고 있습니다. 보유중인 공유자원이 모두 사용 중이면 count변수를 음수로 변경하고 대기 큐에 대기자를 적습니다. 어떤 스레드의 공유자원 사용이 끝나면 count변수를 1 증가시키고 대기 큐의 스레드를 깨웁니다.

수도코드로 표현하면 다음과 같습니다.

semaphore s;
sem_init(s, num_of_shared_resources); // 초기화
sem_wait(s); // 대기
use_shared_resources(); // 공유자원 활용
sem_signal(s); // 자원 반납

int sem_wait(semaphore s){
		s--;
		if(s<0) wait;	
}
int sem_signal(semaphore s){
		s++;
		if(exist_waiting) wake_process;
}

한마디로 세마포어는 공유자원의 접근을 제한하는 정수형 변수를 이용해서 공유 자원에 대한 접근을 제한하는 방법을 말합니다.

정리

뮤텍스세마포어공유 자원에 대한 접근을 제어하기 위한 동기화 매커니즘입니다.
뮤텍스임계 규역에 하나의 스레드만 진입이 가능합니다.
세마포어임계 구역에 여러 스레드가 진입할 수 있습니다.

References

profile
기록하고 정리하는 걸 좋아하는 개발자.

0개의 댓글