책너두 5기 47일차

로버트 C. 마틴의 클린코드 p. 429~ p.436

내용정리

부록 A 동시성 2

작업 처리량 높이기

동기화 영역은 언제나 작을수록 좋다.

작업 처리량 계산 - 단일 스레드 환경

다음을 가정한다.

  • 페이지를 읽어오는 평균 I/O 시간 : 1초
  • 페이지를 분석하는 평균 처리 시간: 0.5초
  • 처리는 CPU 100%를 사용, I/O는 CPU 0% 사용

스레드 하나가 N 페이지를 처리한다면 총 실행 시간은 1.5초 * N이다.

작업 처리량 계산 - 다중 스레드 환경

3개의 스레드를 사용한다면? 페이지 읽기 한 번은 페이지 분석 두 번과 겹침이 가능하므로 일 초마다 두 페이지를 처리한다. 따라서 단일스레드보다 처리율이 세 배 높다.

데드락

다음 4가지 조건을 모두 만족하면 발생한다.

  • 상호 배제(Mutual exclusion)
  • 잠금 & 대기(Lock & Wait)
  • 선점 불가(No Preemption)
  • 순환 대기(Circuar Wait)

상호 배제(Mutual Exclusion)

여러 스레드가 한 자원을 공유하나 그 자원은

  • 여러 스레드가 동시에 사용하지 못하며
  • 개수가 제한적이라면

이 조건을 만족한다.

잠금 & 대기(Lock & Wait)

일단 스레드가 자원을 점유하면 필요한 나머지를 모두 점유해 작업을 마칠 때까지 점유한 자원을 내놓지 않는다.

선점 불가(No Preemption)

한 스레드가 다른 스레드로부터 자원을 빼앗지 못한다.

순환 대기(Circular Wait)

죽음의 포옹(deadly embrace)이라고도 한다.

  • T1이 R1을 점유하고 T2가 R2를 점유한다.
  • T1은 R2가 필요하고 T2도 R2가 필요하다.

서로 물려있는 상황이다.

위 4가지 조건 중 하나라도 깨면 데드락을 해결할 수 있다.

  • 상호 배제 조건 깨기
    • 동시에 사용해도 괜찮은 자원을 사용한다.
    • 스레드 수 이상으로 자원 수를 늘인다.
    • 자우너을 점유하기 전에 필요한 자원이 모두 있는지 확인한다.
  • 잠금 & 대기 조건 깨기
    • 각 자원을 점유하기 전에 확인하여 어느 하나라도 점유하지 못한다면 지금까지 점유한 자원을 몽땅 내놓고 처음부터 다시 시작한다.
    • 기아(Starvation) : 한 스레드가 계속해서 필요한 자우너을 점유하지 못하는 것
    • 라이브락(Livelock) : 여러 스레드가 한꺼번에 잠금 단계로 진입하는 바람에 계속해서 자원을 점유했다 내놨다를 반복하는 것
    • 기아와 라이브락이 발생할 수 있다.
  • 선점 불가 조건 깨기
    • 간단한 요청 메커니즘으로 처리한다.
    • 필요한 자원이 잠겼다면 자원을 소유한 스레드에게 풀어달라 요청한다. 소유 스레드가 다른 자원을 기다리던 중이었다면 자신이 소유한 자우너을 모두 풀어주고 처음부터 다시 시작한다.
  • 순환 대기 조건 깨기
    • 모든 스레드가 일정 순서에 동의하고 그 순서로만 자원을 할당한다면 데드락은 불가능하다.
    • 하지만 자원을 할당하는 순서와 자원을 사용하는 순서가 다를지도 모른다. 그래서 맨 청므 할당한 자원을 아주 나중에야 사용할 수도 있다.
    • 혹은 순서에 따라 자원을 할당하기 어려울 수 있다. 첫 자원을 사용한 후에야 둘째 자원 ID를 얻는다면 말이다.

모든 조건이 단점이 있지만 공짜 점심은 없는 법이다.