독서일지/클린 코드

클린 코드 독서일지 - Day 46

Sadie Kim 2023. 12. 26. 01:23

작업 처리량 높이기

URL 목록을 받아 네트워크에 연결한 다음 각 페이지를 읽어오고 분석하여 통계 보고서를 출력하는 코드를 짠다고 가정.

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

편의상 다음과 같이 가정

  • 페이지를 읽어오는 평균 I/O 시간 1초
  • 페이지를 분석하는 평균 처리 시간 0.5초
  • 처리는 CPU를 100% 사용하고 I/O는 0% 사용
    => 스레드 하나가 N페이지를 처리하면 총 실행 시간은 1.5초*N

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

여러 스레드를 사용하면 프로세서를 사용하는 페이지 분석과 I/O를 사용하는 페이지 읽기를 겹쳐 실행할 수 있음
=> 단일스레드의 세 배의 처리율로 처리 가능

데드락

다음 네 가지 조건을 모두 만족하면 데드락이 발생

  • 상호 배제 : 여러 스레드가 한 자원을 공유하나 그 자원은 여러 스레드가 동시에 사용하지 못하며 개수가 제한적임
  • 잠금&대기 : 일단 스레드가 자원을 점유하면 작업을 마칠 때까지 이미 점유한 자원을 내놓지 않음
  • 선점 불가 : 한 스레드가 다른 스레드로부터 자원을 빼앗지 못함
  • 순환 대기 : T1, T2라는 스레드 두 개가 있고 R1, R2라는 자원 두 개가 있을 때, T1이 R1을 점유하고 T2가 R2를 점유하면서 각자 점유하지 않은 자원을 필요로 할 때

데드락 피하기

상호 배제 조건 깨기

다음 방식으로 조건 깰 수 있음

  • 동시에 사용해도 괜찮은 자원 사용하기
  • 스레드 수 이상으로 자원 수 늘리기
  • 자원을 점유하기 전에 필요한 자원이 모두 있는지 확인하기
    But. 대다수 자원에겐 해당되지 않음

잠금 & 대기 조건 깨기

각 자원을 점유하기 전에 모든 자원을 점유할 수 있는지 확인하고, 만약 어느 하나라도 점유하지 못한다면 지금까지 점유한 자원을 몽땅 내놓고 처음부터 다시 시작하기
But. 잠재적인 문제가 몇 가지 있음

  • 기아 : 한 스레드가 계속해서 필요한 자원을 점유하지 못하는 것
  • 라이브락 : 여러 스레드가 한꺼번에 잠금 단계로 진입하는 바람에 계속해서 자원을 점유했다 내놨다를 반복하는 것
    두 경우 모두 작업 처리량을 크게 떨어뜨림 -> 기아는 CPU 효율을 저하, 라이브락은 쓸데없이 CPU만 많이 사용
    => 모든 전략이 실패할 때 꺼내 들 수 있는 카드.

선점 불가 조건 깨기

다른 스레드로부터 자원을 뺏어올 수 있게 하는 것
-> 필요한 자원이 잠겼다면 자원을 소유한 스레드에게 풀어달라 요청하고, 소유 스레드가 다른 자원을 기다리던 중이었다면 자신이 소유한 자원을 모두 풀어주고 처음부터 다시 시작
But. 이 모든 요청을 관리하기가 간단하지 않음

순환 대기 조건 깨기

데드락을 방지하는 가장 흔한 전략. 모든 스레드가 일정 순서에 동의하고 그 순서로만 자원을 할당하는 것
But. 다음과 같은 문제의 소지 있음

  • 자원을 꼭 필요한 이상으로 오랫동안 점유할 수 있음
  • 때로는 순서에 따라 자원을 할당하기 어려움 -> 첫 자원을 사용한 후에야 둘째 자원 ID를 얻는다면 순서대로 할당하기 불가능

모든 전략이 장단점이 있음.
프로그램에서 스레드 관련 코드를 분리하면 조율과 실험이 가능하므로 통찰력이 높아져 최적의 전략을 찾기 쉬워짐