운영체제13 - 컨디션 변수, 세마포어 그리고 교착상태

운영체제를 공부하기 위해 운영체제 아주 쉬운 세 가지 이야기 라는 책을 읽고 공부한 내용을 정리합니다.
잘못되거나 부족한 부분이 있으면 언제든 댓글로 가르침 부탁드립니다.

목차

  1. 컨디션 변수란?
  2. 세마포어
  3. 병행성 관련 오류

1. 컨디션 변수란?

쓰레드가 계속 진행되기 위해서는 특정 조건이 만족하는지 검사해야 하는 경우가 발생한다. 이떄 컨디션 변수 를 활용할 수 있다. 컨디션 변수는 어떤 실행의 상태가 원하는 것과 다를 때 조건이 참이 되기를 기다리며 스레드가 대기할 수 있는 큐이다. 또한 컨디션 변수에는 2개의 연산이 있다.

  • wait() : 조건이 만족하지 않아 스레드를 재운다.(큐에 넣는다.)

  • signal() : 조건이 만족해서 다른 스레드를 깨운다.

  • wait은 락을 갖고 있다고 가정하고 작동되기 때문에, 호출자를 잠들게 할 떄 락을 해제하고 리턴하기 직전에 락을 다시 획득해야 한다.

2. 세마포어

2.1 세마포어의 정의

세마포어를 ‘공유 자원에 접근할 수 있는 권한의 개수이자, 음수일 때는 대기중인 스레드의 개수’ 정도로 이해하면 조금 더 쉽게 이해할 수 있다. 세마포어는 정수 값을 갖는 객체로서, 락과 컨디션 변수 모두로 사용할 수 있다. POSIX 표준에 따라, sem_wait()sem_post() 2개의 루틴을 통해 세마포어를 조작한다.

  • sem_wait()

    int sem_wait() {
    // semaphore 값 1 감소
    // semaphore < 0 이면 wait (spin 혹은 sleep)
    }
  • sem_post()

    int sem_post() {
    // semaphore 값 1 증가
    // 대기하고 있는 스레드가 1개 이상 있다면, 하나를 깨운다.
    }

2.2 이진 세마포어 (binary semaphore)

세마포어를 통해 락을 구현하는 것을 이진 세마포어라고 한다. 처음 세마포어의 값은 1이다. 즉, 공유 자원 접근 권한이 1개 있다는 뜻이다. 이때 스레드가 sem_wait()을 실행하면 세마포어를 1 감소시켜 0으로 만들고, 음수가 아니므로 대기없이 바로 sem_wait()에서 빠져나와 임계영역에 진입할 수 있다. 그리고 그 사이 다른 스레드의 접근이 없다면 임계영역 작업을 마치고 sem_post()를 통해 다시 세마포어 값을 1로 원상복귀 시킨다. 만약 세마포어가 0 일때 다른 스레드가 sem_wait()을 실행한다면 세마포어값은 음수가 되고 스레드는 대기 상태가 된다.

2.3 계수형 세마포어 (counting semaphore)

이진 세마포어와 거의 똑같다. 다만 세마포어를 초기화 시킬 때, 공유 가능한 자원의 개수만큼 세마포어의 값을 초기화시켜주면 된다.

3. 병행성 관련 오류

3.1 비교착 상태 오류

  1. 원자성 오류 : 다수의 메모리 참조 연산자들 간에 있어 예상했던 직렬성이 보장되지 않은 경우 발생 - 락으로 해결
  2. 순서 위반 오류 : 메모리 참조 간의 순서가 바뀐 경우 발생 - 컨디션 변수로 해결

3.2 교착 상태 (deadlock)

교착상태란 서로가 상대방의 자원이 내놓아지기만을 무한정 기다리는 상황을 의미한다. 교착 상태가 발생하기 위해서는 아래 4가지 조건이 모두 충족되어야 한다.

  1. 상호 배제(Mutual Exclusion)
    스레드가 자신이 필요로 하는 자원에 대한 제어권을 주장할 수 있다.(락 획득)
  2. 점유 및 대기 (Hold-ad-wait)
    스레드가 자신에게 할당된 자원을 점유한 채로 다른 자원을 대기한다.
  3. 비 선점 (No Preemption)
    자원(락)을 소유하고 있는 스레드로 부터 자원을 강제로 뺴앗을 수 없다.
  4. 환형 대기 (Circular wait)
    각 쓰레드는 다음 쓰레드가 요청한 하나 또는 그 이상의 자원을 갖고 있는 쓰레드들의 순환고리가 있다.

3.3 교착 상태의 예방

  1. 상호 배제의 제거
    상호 배제 자체를 없애야 하지만, 일반적인 코드에는 임계 영역이 있기 때문에 제거가 쉽지 않다.
  2. 점유 및 대기의 제거
    필요한 자원이 모두 할당될 때만 자원을 점유하고, 하나라도 부족한 자원이 있다면 할당하지 않도록 한다.
  3. 비 선점의 제거
    점유 및 대기의 제거와 비슷하게, 자원을 소유한 프로세스 A가 다른 자원을 추가로 요구했는데 이미 다른 프로세스 B가 점유하고 있는 경우, A 자신의 자원을 내놓도록하고 B의 자원을 기다린다.
  4. 환형 대기의 제거
    자원 할당 순서를 정해 순서대로 자원을 할당하도록 한다.
Published 1 Oct 2019


jaegoon on github