[이것이 취업을 위한 컴퓨터 과학이다] : 운영체제 - 동기화와 교착상태

프로세스 간 통신 / 스레드 간 통신

공유자원: 프로세스 혹은 스레드가 공유하는 자원

임계구역: 다수의 프로세스 혹은 스레드가 동시에 공유자원에 접근할 경우 실행에 문제가 발생할 수 있는 코드

레이스 컨디션: 프로세스 혹은 스레드가 동시에 임계 구역의 코드를 실행하여 문제가 발생하는 상황

-> 레이스 컨디션이 발생하면 자원의 일관성이 손상 될 수 있다.

-> 레이스 컨디션을 방지하면서 임계구역을 관리하기 위해서는 프로세스와 스레드가 동기화 되어야한다.

동기화

다음의 2가지 조건을 준수하며 실행 하는 것

  • 실행 순서 제어: 프로세스 및 스레드를 올바른 순서로 실행하기
  • 상호배제: 동시에 접근 해서는 안되는 자원에 하나의 프로세스 및 스레드만 접근하기

-> 실행순서제어를 위한 동기화, 상호배제를 위한 동기화가 있다.

 

동기화 기법

✔️ 뮤텍스 락

동시에 접근해서는 안되는 자원에 동시 접근이 불가능하도록 상호 배제를 보장하는 동기화 도구이다.

 

❓ 뮤텍스 락의 원리

임계 구역에 접근하고자 한다면 반드시 락(lock)을 획득(acquire) 해야하고,
임계구역에서의 작업이 끝났다면 락을 해제(release) 해야한다.

 

  • 프로세스 및 스레드가 공유하는 변수(lock)와 2개의 함수(acquire, relese)로 구현된다.
  • aquire() : 락을 획득하기 위한 함수
  • release() : 획득한 락을 해제하기 위한 함수
  • lock.acquire()을 호출하더라도 바로 lock을 얻을 수는 없고 lock이 해제 될 때까지 기다려야한다.

✔️ 세마포

한번에 3,4개의 프로세스 및 스레드까지 특정 자원을 이용할 수 있는 상황에 이용하는 동기화 기법이다.

프로세스 및 스레드가 임계 구역 앞에서 멈추라는 신호를 받으면 잠시 기다리고, 가도 좋다는 신호를 받으면 그때 임계구역에 들어가도록 하는 기법이다.

 

  • 변수 S: 사용가능한 공유 자원을 개수를 나타내는 변수
  • wait() 함수: 임계구역 진입 전 호출하는 함수
  • signal() 함수: 임계구역 진입 후 호출하는 함수

Wait()

가장 먼저 '사용가능한 공유자원의 개수'를 나타내는 변수 S를 1 감소 시킨다.

S가 0보다 작은지 확인한다.

S가 0이상이면 -> wait를 호출한 프로세스 및 스레드는 임계구역으로 진입한다.

S가 0미만이면 -> wait를 호출한 프로세스 및 스레드는 대기 상태로 전환되어 임계구역에 진입할 수 없다.

 

Signal() 

가장 먼저 '사용가능한 공유자원의 개수'를 나타내는 변수 S를 1 증가시킨다.

S가 0 이하인지 확인한다.

S가 0 초과이면 -> 사용가능한 공유자원의 개수가 1개이상 남았다는 것이다.

S가 0 이하이면 -> 임계 구역에 진입하기 위해 대기하는 프로세스가 존재한다는 것이다. -> 이경우에 대기상태 프로세스 중 하나를 준비상태로 전환한다.

✔️ 조건 변수와 모니터

조건변수

실행 순서 제어를 위한 동기화 도구이다. 특정 조건 하에 프로세스를 실행/일시 중단함으로써 프로세스나 스레드의 실행순서를 제어할 수 있다.

조건변수에 대해 wait(), signal() 함수를 호출할 수 있다.

 wait() -> 호출한 프로세스 및 스레드의 상태를 대기상태로 전환하는 함수

signal() -> wait()로 일시 중지된 프로세스 및 스레드의 실행을 재개하는 함수

 

특정 프로세스가 실행될 조건이 되지 않았을 때 wait를 통해 실행을 중단하고, 조건이 충족되었을 때는 signal을 통해 실행을 재개한다.

 

모니터

공유 자원과 그 공유 자원을 다루는 함수로 구성된 동기화 도구이다.

상호배제를 위한 동기화 뿐 아니라 실행 순서 제어를 위한 동기화까지 가능하다. 

 

❓모니터의 작동 원리

프로세스 및 스레드는 공유자원에 접근하기 위해 반드시 정해진 공유 자원 연산을 통해 모니터 내로 진입해야하고, 
모니터 안에 진입하여 실행되는 프로세스 및 스레드는 항상 하나여야한다. 
이미 모니터 내로 진입하여 실행중인 프로세스 및 스레드가 있다면 큐에서 대기해야 한다.

 

여기서 조건변수를 활용하면 실행 순서 제어를 위한 동기화도 구현 할 수 있다.

스레드 안전

멀티스레드 환경에서 어떤 변수나 함수, 객체에 동시 접근이 이루어져도 실행에 문제가 없는 상태를 의미한다. 

레이스 컨디션 발생 -> 스레드 안전 X

레이스 컨디션 X -> 스레드 안전

 

교착 상태

일어나지 않을 사건을 기다리며 프로세스의 진행이 멈춰 버리는 현상을 말한다.

✔️ 교착 상태의 발생조건

4개의 조건이 모두 만족할때 교착 상태가 발생할 가능성이 생긴다.

  1. 상호 배제
    한 프로세스가 사용하는 자원을 다른 프로세스가 사용할 수 없는 상황
  2. 점유와 대기
    한 프로세스가 어떤 자원을 할당받은 상태에서 다른 자원 할당받기를 기다리는 상황
  3. 비선점
    어떤 프로세스도 다른 프로세스의 자원을 강제로 빼앗지 못하는 경우
  4. 원형 대기
    각 프로세스가 서로 점유한 자원을 할당받기 위해 원의 형태로 대기할 경우

✔️ 교착 상태 해결 방법

  1. 교착 상태 예방
    교착 상태를 발생시키는 4가지 중 하나를 충족하지 못하게 하는 방법이다.
  2. 교착 상태 회피
    교착 상태가 발생하지 않을 정도로만 조심하면서 자원을 할당한다.
    교착상태가 한정된 자원의 무분별한 할당으로 인해 발생하는 문제로 간주한다.
  3. 교착 상태 검출 후 회복
    프로세스가 자원을 요구하면 그때마다 자원을 할당하고, 주기적으로 교착상태를 검사한다.
    교착상태가 검출 되면 자원 선점을 통해 회복시키거나, 교착 상태에 놓인 프로세스를 강제종료하여 회복시킨다.
    자원 선점을 통한 회복 -> 교착 상태가 해결될 때까지 다른 프로세스로부터 강제로 자원을 빼앗아 한 프로세스에 몰아서 할당하는 것이다.