운영체제

[OS] Mutex, Semaphore 동기화, Busy waiting

KyooDong 2020. 11. 28. 04:42
728x90

Mutex Locks

OS 가 Critical section 문제를 해결하기 위해 가장 간단하게 제공하는 솔루션임

Atomic 하게 수행되는 acquire(), release() 함수를 통해 이를 수행함

acquire() = Lock 을 얻어 C.S.에 접근하는 함수

release() = C.S. 작업을 모두 마쳐 Lock 을 해제하는 함수

단점 : busy waiting ( = Lock 을 얻을 때까지 의미 없이 접근을 시도하는 것. 이러한 Lock 을 spinlock 이라함)

Semaphore

Mutex lock 은 자원의 개수가 여러개 일 때에도 하나의 스레드만 접근을 허용하는데 세마포어는 개수까지 고려하여 N개의 프로세스가 동시에 접근할 수 있도록 함

wait(), signal() 함수를 통해 구현

wait(S) { 
  while ( S <= 0); // busy wait
  S--;
}
signal(S) {
	S++;
}
  • Counting semaphore = 세마포어가 정수의 값을 가짐 = N 개의 프로세스가 동시 접근 가능

  • Binary semaphore = 세마포어가 0 또는 1의 값만 가짐 = mutex lock 과 동일

wait(), signal() 함수 내부의 S 자체도 공유변수이기 때문에 Critical section 문제가 생길 수 있기에 커널과 하드웨어가 두 함수는 atomic, exclusive 하게 동작함을 보장해줘야함

단점 : busy waiting

No busy waiting Semaphore

struct {
  int S; // 세마포어
  struct process *list; // 대기중인 PCB 링크드 리스트
}

block() : wait() 함수 내부에서 실행되며, list 에 자기 자신을 등록하고 sleep() 하는 함수

wakeup() : signal() 함수 내부에서 실행되며, 대기하고 있는 프로세스가 있다면 그 중 한 프로세스를 깨워줌

 

S 가 음수이면 대기 중인 프로세스를 의미하며, 양수이면 가용한 리소스의 양을 의미함

프로그래머가 세마포어를 제대로 사용하지 못하는 경우

  • signal(mutex) - wait(mutex) : 깨운다고 생각했는데 잠들기 전에 깨우고 잠듦

  • wait(mutex) - wait(mutex) : 아무도 깨워주지 않음 Deadlock

  • wait(mutex) 또는 signal(mutex) 를 하나씩 빼먹는 경우

Deadlock 이나 Starvation 이 발생 가능함