책너두 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를 얻는다면 말이다.
모든 조건이 단점이 있지만 공짜 점심은 없는 법이다.