[운영체제] Mutex Lock, Semaphore

Seokjun Moon·2023년 5월 12일
0

운영체제

목록 보기
21/23
post-custom-banner

Mutex Locks

하드웨어 명령어들은 복잡하기 때문에 성능과 프로세스 실행에 있어서 문제를 일으킬 수 있습니다. 따라서 커널 라이브러리를 통해 기능을 제공합니다. 그 중 가장 간단한 방법이 Mutex lock 입니다.

  • 들어갈 때 : acquire()
  • 나올 때 : release()

위 두 함수는 atomic 한 명령어 입니다.

CS Problem Using Mutex Lock

do {
	acquire(lock);

	// critical section

	release(lock);

	// remainder section
} while (true);

acquire() {
	while (!available) ; // busy-waiting
	available = false;
}

release() {
	available = true;
}

이런식으로 동작합니다. 이 때, acquire() 에서 busy-waiting이 발생합니다. (CPU 시간은 사용하는데, 무의미하고 무조건적인 대기로 CPU 낭비를 일으키는 시간)

Busy-Waiting ( = spinlock )

  • 지속적인 반복은 multi-programming 시스템에서는 문제 → 다른 프로세스의 생산적인 작업을 할 수 있는 시간을 낭비하기 때문
  • 프로세스가 대기 중일 때 일시적으로 sleep 후 lock 이 해제되면 wakeup 하는 방식도 존재 → context-switch 가 일어나서 overhead 가 커짐
  • 짧은 시간 대기가 예상될 경우 spinlock 이 유용




Semaphores

Mutex는 두 스레드 간 경쟁만을 지원하는 반면, Semaphore는 여러 스레드 간 경쟁도 지원할 수 있습니다. 2개의 atomic operation 을 이용합니다.

  • wait() : 사용 대기!
  • signal() : 사용 끝!

구현은 다음처럼 이루어집니다.

wait(S) {
	while (S <= 0) ; //busy-waiting
	S--;
}

signal(S) {
	S++;
}

범용성이 좋아 많이 사용됩니다. semaphore 에는 2가지 종류가 있습니다.

  • counting semaphore : 제한 없는 정수 값
  • binary semaphore : 0 또는 1만 가능 ( → mutex lock)

CS 시작 전에 wait(), 끝나고 signal() 을 호출하므로써 해결할 수 있지만, 여전히 busy-waiting이 존재합니다.

Semaphore with no Busy waiting

2가지 operation 이 추가됩니다.

  • sleep() : 해당 프로세스를 waiting queue 로 보냅니다.
  • wakeup() : waiting queue에 있는 프로세스 하나를 ready queue 로 보냅니다.

이를 이용하여 구현하면

이러한 모습입니다. 하지만 문제점이 발생합니다. 오히려 CS를 더 만들어버리는 상황이 발생합니다. 따라서 일반적으로는 busy-waiting이 발생해도 그대로 두는 편입니다. 하지만, CS를 지나치게 오래 점유하는 프로세스와 협업하는 경우에는 busy-waiting₩이 비효율적이므로 다른 대책이 필요합니다.

profile
차근차근 천천히
post-custom-banner

0개의 댓글