CH.14) 동기화

songtofu·2023년 1월 14일
0

전문가를 위한 C

목록 보기
10/10

앞서

  • 프로그램에서 동시성을 사용한 결과 나타날 수 잇는 문제를 집중적으로
  • 동시성 관련 문제, 경쟁 상태 및 데이터 경쟁
  • 고유 상태에 대한 접근을 동기화하기 위해 사용하는 동시성 제어 기술
  • POSIX에서의 동시성

14.1 동시성 문제

  • 동시성 문제에 대한 여러 유형
    1. 동시성 제어 메커니즘이 없을 때 존재
    -> 전체 상태를 다르게 만들 때 동시성 문제 발생
    1. 동시성 제어 기술을 사용해서 발생
      -> 수정 사항이 적용된 이후에만 발생(= 동시성 문제를 고칠 떄 속성 및 근본 원인이 완전이 다른 새로운 문제가 야기될 수 있음)
  • 기아 상태: 일부 작업들이 데이터 자원에 아예 접근하지 못하게 되었음.
  • 동시성 문제
    1. 제어(동기화) 메커니즘이 없는 동시 시스템에서 발생하는 문제로, 고유한 동시성 문제 : 모든 동시 시스템에 본질적으로 존재
    1. 첫 번째 문제를 해결하려고 시도한 이후 발생하는 문제, 동기화 이후 문제: 개발자가 일으킨 새로운 버그

14.2 고유한 동시성 문제

  • 목표: 제약 조건이 변경되지 않으며 불변함을 유지하도록 동기화 매커니즘이라는 제어 메커니즘을 도입하는 일
  • 시스템의 불변 제약 조건을 만족하지 않는 인터리빙 존재 = 시스템에 경쟁 상태가 발생했다고 함.
  • 경쟁 상태: 동시 시스템의 고유한 속성 -> 시스템읩 불변 제약 조건을 지키지 못할 위험 ex. 카운터 공유 변수
  • 경쟁 상태는 임계 구역이라는 작은 명령어 집합이 순서대로 실행되지 않을 때만 발생
  • 작성 가능한 공유 상태와 특정 불변 조건이 둘 다 잇다면 공유 상태를 목표로 하는 읽기와 쓰기 명령어 간에 엄격한 순서를 부과할 수 있다.
  • 데이터 무결성? 모든 작업이 언제나 공유 상태의 최신값을 읽을 수 있어야 한다.
  • 데이터 경쟁 발생할면 서로 다른 작업 간에 공유 상태가 있어야하고, 공유 상태는 반드시 최소한 하나 이상의 작업이 수정 할 수 있어야함.

14.3 동기화 이후 문제

  • 제어 메커니즘을 잘못 사용한 결과 예상되는 주요 문제 4가지
    1. 새로운 고유한 문제
    1. 기아 상태
    2. 교착 상태
    3. 우선순위 역전
  • 개발자가 제어 메커니즘을 도입해야만 기아 상태가 발생, 교착 상태 역시 개발자가 관여하기 전까지 동시 시스템에 존재 X. 교착 상태 더 흔한 문제

14.4 동기화 기술

  • 동시 시스템 각각 고유한 불변 제약 조건 있음, 모든 인터리빙이 이 조건을 충족하지는 X.
  • 불변 제약 조건을 만족하면서 나쁜 인터리빙을 대체하는 새로운 인터리빙을 생성해야함.
  • 동기화 기술을 도입하려면 새로운 코드를 작성하고 기존 코드를 변경해야함.
  • 새 인터리빙의 동시성 문제 해결 방법? 서로 다른 작업의 다른 명령어 사이에 발생 전 제약을 추가로 부과, 이는 불변 제약 조건을 만족.
  • 참고, 단일 작업 두 개의 인접한 명령어 사이에는 항상 발생 전 제약 조건이 존재. 동시 시스템에서는 서로 다른 두 작업에 잇는 두 명령어 사이에 제약 조건이 없으며, 동기화 기술을 사용해 두 작업 사이의 실행 순서를 제어하는 새로운 발생 전 제약 조건을 정의.
  • 완전히 새로운 동시 시스템 = 새로운 다른 문제 있다.

14.4.1. 바쁜 대기 및 스핀 락

  • 작업을 후속 작업이 명령어를 실행할 때까지 멈춰서 대기.
    이후 두 가지 선택 가능
    1. 후속 작업이 완료되었는지 다시 한번 확인
    2. 후속 작업이 이전 작업에 대해 이제 명령어를 계속해서 실행해도 된다고 알리기.
  • 효율적X. 이벤트가 발생하기를 기다리는 간단한 방식. 낭비되는 시간이 짧으리라 예측되는 환경에서 바쁜 대기 사용.

14.4.2. 잠자기/알림 메커니즘

  • 작업이 잠들 때 이점? CPU 시간 낭비 X
  • 잠자기 모드가 될 때 깨워줄 메커니즘 필요. (= 알림, 신호전달)
  • 불리언 플래그 사용

14.4.3. 세마포어와 뮤텍스

  • 세마포어? 공유 자원에 대한 접근을 동기화할 때 사용하는 변수 또는 객체
  • 세마포어의 특정 유형인 뮤텍스
  • 세마포어? 유사 비서, 의사? 공유 자원, 진료실? 임계 구역
  • 임계 구역? 세마포어가 보호하는 간단한 명령어 집합
  • 세마포어의 범주는 두 개 이상(세마포어가 생성될 댸 정의된 특정 숫자까지)의 작업이 임계 구역에 들어가도록 할 수 있음. 한 번에 하나의 작업만 임계 구역으로 들어가게 하는 세마포어 = 뮤텍스
  • 뮤텍스 : 경쟁 상태가 없는 상호 배제를 기반으로 한 해결 방법을 위해 충족해야할 사항
    1. 언제든 작업 중 하나만 임계 구역에 들어갈 수 잇음. 다른 작업은 이 작업이 임계구역을 떠날 떄 까지 기다려야함
    1. 해결 방법에는 교착 상태 존재 X. 임계 구역에 입장하기를 기다리는 작업은 결국 들어갈 수 있어야함. 대기 시간의 상한선(경합 시간)을 정한다.
  • 임계 구역에 잇는 작업은 다른 작업이 임계 구역이 들어가기 위해 선점해 빼낼 수 없습니다. (= 선점 O, 협조적)
  • 세마포어를 기다리는 행위와 임계 구역에 입장하는 행위는 세마포어 잠금과 같다.
  • 세마포어를 떠나거나 세마포어를 업데이트하는 것 역시 세마포어 잠근 해제와 같다.
  • 경합 상태에서 작업이 대기하는 시간 = 경합 시간

14.4.4. 멀티프로세서 유닉

  • 코어가 하나뿐인 CPU. 프로세서 유닛이 하나만 존재: 메인 메모리의 특정 주소에 접근하려는 작업들은 주소가 CPU 코어에 캐시되어 있어도 언제나 최신값을 읽음.
  • CPU 코어 내부에 있는 특정 메모리 주솟값은 지역 캐시에 저장, 해당 주소에 대한 변경 사항도 캐시 내에 유지. 이 방식은 메인 메모리에서 읽기 및 쓰기 작업의 횟수를 줄여서 성능을 향상.
  • 특정 이벤트에서 CPU 코어는 캐시와 메인 메모리가 동기화되도록 지역 캐시에 있는 변경 사항을 다시 메인 메모리로 전파.
  • 지역 캐시들은 프로세서 유닛이 두 개 이상일 때도 존재
  • 멀티 프로세서 유닛? 두 개 이상의 코어가 있는 CPU 또는 코어 수 상관 X, CPU가 여러 개인 것. 모든 CPU 코어는 고유한 지역 캐시를 가짐.
  • CPU 코어 간 메모리 일관성 프로토콜을 도입해 해결
  • 메모리 주소가 서로 다른 모든 프로세서에 보인다는 것
  • 다른 프로세서 유닛에서 실행 중인 모든 작업에 메모리 가시성이 도입
  • 메모리 장벽 사용: 실행(쩐달) 시 장벽과 같은 역할을 하는 명령어, 하나의 지역 캐시에 잇는 모든 값은 메인 메모리 및 다른 지역 캐시로 전파. (= 메모리 장벽은 모든 CPU 코어의 지역 캐시와 메인 메모리 동기화)
  • 세마포어에 대한 잠금 & 해제 = 메모리 장벽으로서의 역할, 모든 CPU 코어의 지역 캐시와 메인 메모리를 동기화하기, 최근 변경 사항을 공유 상태로 전파하기
  • 작업이 뮤텍스(or 세마포어)를 잠글 떄, 뮤텍스가 자동으로 해제되는 3가지 경우
    1. 작업이 Unlock 명령어를 사용하면 뮤텍스 해제
    1. 작업이 완료 -> 잠긴 뮤텍스 해제
    2. 작업이 잠자기 모드 -> 잠겼던 뮤텍스 해제 (일반적 x)
  • 직업이 뮤텍스를 잠갔을 떄, 작업이 다시 뮤텍스를 잠글 수 X.
  • 여기서 잠그려 하며 대게 교착 상태가 된다.
  • 재귀적인 뮤텍스? 여러 번 잠그기 ㅇ.
  • 몇 번 잠갔든지 간에 재귀적 뮤텍스가 잠금 상태일 댸 다른 모든 작업이 이를 잠그려고 한다면 차단.
  • 잠금과 해제 작업은 언제나 쌍으로 존재.

14.5 스핀락

  • 스핀락? 바쁜 대기 알고리듬
  • 뮤텍스는 메모리 장벽 역할, 메모리 가시성 문제 X, 공유 플래그에 대해 작업 P와 Q를 효과적으로 동기화
  • 뮤텍스가 잠긴 상태로 유지? P가 공유 플래그 완료에 접근할 기회를 찾지 못한다는 의미(반교착 상태) -> 잠금과 해제 명령어 반복을 통해 P가 접근 기회를 찾고 명령어를 통해 플래그 완료를 업데이트 하도록 함.
  • 스핀 락 사용할 떄 작업은 가능한 빨리 뮤텍스를 해제 -> 임계 구역 매우 작아야함.

14.5.1. 조건 변수

  • 조건 변수? 작업을 잠자기 모드로 만들거나 다른 잠든 작업에 알리고 꺠울 수 있다.
  • 작업이 더 이상 CPU 공유를 받지 않는다는 의미.
  • 다른 작업 간에 신호 전달을 하는 데 사용.
  • 조건 변수가 도움이 되려면 여러 작업에서 공유.
  • 공유 자원에 대해 동기화된 접근이 필요하니 유의
  • 임계 구역을 보호하는 뮤텍스로 충족 시킬 수 있따.
  • 뮤텍스 객체와 조건 변수, 동시성과 관련된 설계 패턴 = 모니터 객체

14.6 POSIX의 동시성

  • 멀티프로세싱: 서로 다른 프로세스로 실행
  • 멀티 스레딩: 동일한 프로세스에 잇는 서로 다른 스레드

14.6.1 동시성을 지원하는 커널

  • 한 프로세스는 다른 프로세스로 접근 X.
  • 스레드는 동시적인 방식으로 여러 명령어를 함께 실행하는 여러 실행 스레드를 이용해 단일 프로세스에 동시성을 도입.
  • 단일 스레드는 두 프로세스 간에 공유 X. 스레드를 소유한 프로세스에 국한되어 바인딩된다.
  • 비선점 스케줄링: 작업에 CPU 코어를 부여하고 협력 작업이 CPU 코어를 해제하기를 대기
  • 스케줄러가 선점을 통해 CPU를 회수하려면 우선 순위가 높은 선점 신호가 있어함.
  • 선점 스케줄링(시분할)에서는 스케줄러가 CPU 코어를 회수할 때까지 작업이 CPU 코어를 사용할 수 있다.
  • 우선순위 수준을 다르게 두는 것 = 현대적인 커널의 필요 조건
  • 소프트웨어에 동시성을 도입 방법 2가지
    1. 멀티프로세싱, 다중 작업 환경에서 병렬 작업을 하도록 사용자 프로세스를 사용
    1. 멀티스레딩, 단일 프로세스 내에서 작업을 병렬적인 실행의 흐름으로 분할하기 위해 사용자 스레드를 사용.

14.7 멀티프로세싱

  • 동시 작업을 하는 프로세스를 사용한다는 의미 ex. 공용 게이트웨이 인터페이스 (동시에 여러 요청 처리)

  • 스레드와 프로세스 사이에 공유 상태 도입 => 큰 차이
    1. 사용 가능한 동기화 기술
    API는 유사, 멀티프로세스 환경 작동은 복잡 & 기본 구현 다름

    1. 공유 상태를 사용하는 기술
      프로세스에서 사용할 수 있는 기술을 스레드도 모두 사용할 수 있는 한편, 스레드는 같은 메모리 영역을 사용해서 상태를 공유할 수 잇다는 장점
  • 스레드들은 공유 상태를 저장하기 위해 같은 프로세스의 메모리를 사용할 수 있다.

    14.8 멀티스레딩

  • 동시 환경에서 병렬 작업을 수행하기 위해 사용자 스레드를 이용하는 것

  • 소유자 프로세스가 없는 스레드 존재 X.

  • 최소한 하나의 스레드를 가짐. 이를 메인 스레드라 함.

  • 프로세스 내의 모든 스레드는 같은 메모리 영역에 접근 할 수 있다.

  • 각 스레드 고유한 스택 메모리 잇음. 공유 상태를 유지하는 자리 표시자로 해당 메모리 사용 O.

  • 메모리 주소는 모두 이 프로세스의 스택 세그먼트에 속하기 때문.

  • 스레드는 또한 프로세스가 소유한 동일한 힙 공간에도 쉽게 접근.

  • 스레드의 공유 상태를 저장하는 자리 표시자로 이 힙 공간을 사용 할 수 있다.

profile
읽으면 머리에 안들어와서 직접 쓰는 중. 잘못된 부분 지적 대환영

0개의 댓글