동기화 기법

Sundae·2023년 9월 16일
0

운영체제

목록 보기
9/15
post-thumbnail

동기화 기법


하나에 자원에 여러 프로세스가 동시에 접근하면 문제가 발생할 수 있다.

이에 관련하여, 여러 프로세스가 같이 사용하는 자원인 공유 자원과 자원에 접근하는 코드영역인 임계 구역이 있다.

하나의 프로세스만 임계 구역에 접근할 수 있게 하고 올바른 실행 순서를 보장할 수 있어야 하는데, 이를 위해 뮤텍스 락, 세마포, 모니터라는 기법을 사용한다.

뮤텍스 락


뮤텍스 락의 실행순서를 단순히 표현하면 다음과 같다.

  1. 하나의 프로세스가 임계 구역에 진입한다.
  2. 본 프로세스가 임계 구역에 있음을 알리기 위해 뮤텍스 락을 이용한 lock을 건다.
  3. 다른 프로세스가 임계 구역의 lock이 풀릴 때까지 대기한다.
  4. 처음 임계 구역에 들어갔던 프로세스가 처리를 완료 후, lock을 풀고 임계 구역에서 벗어난다.

위의 실행을 위한 뮤텍스 락의 단순한 구성은 세 가지로 구현할 수 있다.

  • 임계 구역을 잠그기 위해 프로세스들이 공유하는 전역 변수 lock
  • 임계 구역을 잠그는 acquire 함수
  • 임계 구역의 잠금을 해제하는 release 함수

acquire 함수는 프로세스가 임계 구역에 진입하기 전에 호출하는 함수이다.
만약 임계 구역이 잠겨 있다면, lock이 false가 될 때까지 임계 구역을 계속 확인하고, 열려 있다면 임계 구역의 lock을 true로 바꾸는 함수이다

release 함수는 임계 구역에서 작업이 끝나고 호출하는 함수이다. lock을 false로 바꾸는 함수다.

뮤텍스 락은 하나의 프로세스가 lock을 걸고 임계구역에 진입할 때 다른 프로세스는 계속해서 lock이 잠겨있는지 반복해서 확인해야한다. 이런 대기 방식을 바쁜 대기(busy wait)라고 한다.

세마포


세마포는 뮤텍스 락과 달리 공유 자원이 여러 개 있는 상황에서도 적용이 가능한 동기화 기법이다.

세마포의 종류에는 이진 세마포(binary semaphore)와 카운팅 세마포(counting semaphore)가 있다.

카운팅 세마포에 대해서 알아보자.

세마포는 철도 신호기에서 유래한 단어이다. 기차는 신호기가 내려가 있을 때는 '멈춤'신호로 간주하고 잠시 멈춘다. 반대로 올라가 있을 때는 가도 좋다는 신호로 간주하고 다시 움직인다.

세마포는 이와 같이 멈춤 신호를 받으면 잠시 대기하고, 가도 좋다는 신호를 받으면 임계 구역에 들어간다.

세마포는 단순히 다음과 같은 구성으로 구현될 수 있다.

  • 사용 가능한 공유 자원의 개수를 나타내는 전역 변수
  • 임계 구역에 들어가도 되는지, 기다려야 하는지를 알려주는 wait 함수
  • 임계 구역 앞에서 대기하고 있는 프로세스가 진입 해도 되는지 알려주는 signal 함수

위 구성으로 세마포는 다음과 같은 실행 순서로 단순하게 표현할 수 있다.

  1. 임계 구역에 진입할 수 있는 프로세스 개수가 1개 이상인지 계속해서 확인한다.
  2. 임계 구역에 진입할 수 있는 프로세스 개수가 1개 이상이면 임계 구역에 진입할 수 있는 프로세스의 수를 나타내는 전역 변수를 1 감소시키고, 임계 구역에 들어간다.
  3. 임계 구역에서 벗어날 때 전역 변수를 1 상승시킨다.

뮤텍스 락은 바쁜 대기방식을 사용한다고 했다. 만약 임계 구역 앞에서 대기하는 상태라면 계속해서 임계 구역에 진입할 수 있는지 확인해야 하는데, 이런 시간들은 CPU에 낭비가 발생한다.

그래서 세마포는 더 좋은 방법을 사용한다. 만약 임계 구역에 접근을 원하는 프로세스가 대기해야하는 상태라면 wait 함수는 해당 프로세스를 대기 상태로 만들고, 프로세스의 PCB를 대기 큐에 삽입한다. 그리고 임계 구역에 진입할 수 있는 상태가 되면, signal 함수를 호출하여 대기 큐에 있는 대기 중인 프로세스를 준비 상태로 변경한 후 준비 큐로 옮겨준다.

모니터


모니터(monitor)는 공유 자원과 공유 자원에 접근하기 위한 인터페이스(통로)를 묶어 관리한다.

프로세스들은 반드시 인터페이스를 통해서만 공유 자원에 접근할 수 있다.

이를 위해 모니터를 통해 공유 자원에 접근하기 위한 프로세스를 큐에 삽입하고 삽입된 순서대로 공유 자원에 접근할 수 있도록 한다.

또한 모니터는 실행 순서 제어를 위한 동기화도 제공한다.
프로세스를 실행하고 일시 중단하기 위해 조건 변수(condition Variable)를 사용한다.
조건 변수는 프로세스나 스레드의 실행 순서를 제어하기 위해 사용하는 특별한 변수이다.

각 조건 변수에 대응하는 큐가 있는데, 조건 변수는 wait 함수와 signal 함수를 수행할 수 있는다. 예를 들어, 모니터에 진입한 어떤 프로세스가 x.wait()를 통해 wait 함수를 호출 했다.
그 프로세스는 조건 변수 x에 대한 큐에 삽입되게 된다. 그렇기에 다른 프로세스가 모니터 안에 들어올 수 있게 된다.

프로세스가 x에 대한 큐에 삽입되어 대기하다가, x.signal()이 호출 되면 이때 x에 대한 큐에 대기 중이 었던 프로세스가 깨어나 다시 모니터에 들어올 수 있다.

profile
성장 기록 / 글에 오류가 있다면 댓글 부탁드립니다.

0개의 댓글