BOOKS

폴부처 7가지 동시성 모델

파란실버라이트 2019. 10. 8. 12:16

옮긴이의 말, 추천의 말, 시작하는 말

  • 쓰레드와 잠금장치를 이용해서 코드를 작성하는 것이 이렇게 어렵고 복잡한 일이었언가?

  • 코드가 멀티스레드 지원이라는 관점에서 보았을때 완전히 엉망인 코드라는 사실

  • 잠금장치가 없는 자료구조(lock-free data structure), STM(software transaction memory), 액터 모델(AKKA 라이브러리)

  • 스스로 잠금장치, 세마포어, 뮤택스 등를 만들고 있는 개발자라면 이책을 반드시 읽어야 한다.

  • 멀티코어, 멀티 스레딩, 동시성, 병력성과 같은 주제가 나오면 머리가 복잡해시는 갤발자도 읽어야 한다.

  • 동시성을 위한 함수형 프로그램의 문제점, GPU를 활용한 병렬 프로세스로 어떻게 빅데이터를 처리할 수 있는지 알아본다.

  • 모든 프로그래머는 동시성 프로그래밍에 대한 사고를 배워야 한다. 객체 지행 프로그래밍에서 동시성 프로그래밍으로 변화고 있다. 

  • 동시성과 병렬성의 차이에 대한 명료한 설명

  • 소프트웨에서 동시성을 다울 수 있도록 실제 프로그래밍 패러다임의 명확한 설명

  • 스레드와 잠금장치에 대한 한계과 그 한계를 어떻게 극복하는지 , 람다 아키택처에서 부터 액터 기반 모델

  • 동시성을 제대로 구현하는 것은 반응성, 장애 허용, 효율성, 그리고 단순성이라는 목적을 구현하는 열회

  • 독자가 특정한 동시성 문제를 해결하기 위해서 어떤 동시성 도구를 사용해야 할지 판단 할 수 있도록 만드는 것

  • 예제 코드를 만드시 공부할 것

  1. 서문

    1. 동시성 혹은 병렬성?
      • 동시성은 여러 일은 한꺼번에 다루는데 관한 것이다. 

        • 교사가 한 학생의 책을 읽는 것을 듣는 동시에 , 다른 학생의 질문에 대답

      • 병렬성은 여러 일을 한꺼번에 실행하는 데 관한 것이다.

        • 교사가 50장의 연하장을 5명의 학생에게 할당하여 10장씩 작성 

      • 동시성과 병렬성은 동시에 가능

        • 교사는 한 학생의 책을 읽는 것을 듣고, 조교는 다른 학생의 질문에 대답

      • 동시성 프로그래밍은 비결정적 , 타이밍에 따라 결과가 달라진다. 

      • 병렬젹 프로그래밍은 비결정성을 내포하지 않는다. 병렬적 프로그래밍을 지원하는 언어들은 병렬코드를 작성하는 방법을 제공한다. 

    2. 병렬 아키택처
      • 비트 수준의 병렬성 : 8비트 컴퓨터가 32비트 수를 더하고 싶으면 8비트 명령들의 수열을 생성해야 한다. 32비트 컴퓨터는 각각 4바이트(32비트) 수를 병렬로 , 즉 한 번의 단계로 처리할 수 있다.

      • 멀티 프로세스 아키텍처 : 공유 메모리(병목 현상) => 분산 메모리(네트워크를 사용) 

    3. 동시성: 멀티코어를 넘어서
      • 동시적인 세계에 맞는 동시적인 소프트웨어

        • 동시성은 방응형 시스템의 핵심이다. 파일을 백그라운드에서 내려받음으로써 사용자가 한 시간동안 모래시계 커서를 들여다보지 않게 해준다. 

      • 분산된 세계에 맞는 소프트웨어

        • 분산 소프트웨어는 특히 장애에 강하다는 장점을 가지고 있다. - 데이타 선터의 분리 , 클러스터

      • 예측 불가능한 세계에 맞는 탄력적 소프트웨어 

        • 동시성은 독립성과 장애 감지를 통해서 탁력성, 혹은 장애 허용을 가능하게 만든다. 

          • 독립성 : 한 작업에서 발생한 장애가 다른 작업에 영향을 주지 않아야 하기 때문

          • 장애 감지 : 한 동작이 장애를 일으켰을 때 다른 작업에 통지가 전달되서 복구 작업이 일어남

        • 순차적으로 동작하는 소프트웨어는 동시적인 소프트웨어가 제공하는 수준의 탄력성이 없다.

      • 복잡한 세계에 맞는 단순한 소프트웨어 

        • 제대로 선택한 언어와 도구를 사용하면 동시성 코드가 순차적인 코드보다 더 단순하고 명쾌하게 작성될 수 있다.

        • 여러 문제를 다루는 복잡한 쓰레드 한 개를 반드는 것보다 , 하나의 문제를 다루는 여러 개의 쓰레드

    4. 일곱 가지 모델
      1. 쓰레드와 잠금장치

        • 아래 동시성의 다양한 모델의 배후에서 동작 

        • 많은 동시성 소프트웨어의 기본적인 선택

      2. 함수형 프로그래밍 

        • 동시성과 병렬성을 잘 지원

        • 가변 상태를 원천적으로 제거했기에 , 쓰레드-안전 보장 , 병렬처리가 쉽다.

      3. 클로저 방식 - 아이덴티티와 상태 분리하기

        • 클로저 언어는 명령형 프로그래밍과 함수형 프로그래밍을 효과적으로 결합 , 둘의 가진 장점 극대화

      4. 액터

        1. 벙용의 동시성 프로그래밍 모델

        2. 공유 메모리와 분산 메모리 아키택처 양측에서 활용 가능

        3. 지리적 분산을 적극 지원하고 , 장애 허용과 탄력성에 대한 지원이 특히 강하다.

      5. 순차 프로세스 통신(CSP)

        1. 액터 모델과 공통점이 많다 

        2. 커뮤니케이션을 위해 액터 같은 개체가 아닌 채널이라는 개념을 사용

      6. 데이터 병렬성

        1. 그래픽 처리를 위해서 GPU가 사용되지만 , 다른 여러가지 작업을 위해 활용가능

      7. 람다 아키텍처

        1. 병렬성이 아니면 빅데이터 처리는 불가능하다.

        2. 맵리듀스와 스트리밍 프로세스의 장점을 겹합해서, 다양한 빅데이터 문제를 해결

      8. 다음의 질문의 염두하며 공부

        • 이 모델은 동시성 문제, 병렬성 문제, 혹은 두개를 모두 해결하는 데 적합한가?

        • 이 모델은 어떤 병렬 아키텍처를 타깃으로 삼고 있는가?

        • 이 모델은 탄력성을 갖춘 코드, 혹은 지리적으로 분산된 코드를 작성할 때 필요한 도구를 제공하는가?

  2. 쓰레드와 잠금장치

    1. 동작하는 가장 단순한 코드
      • 쓰레드와 잠감장치는 사용할 때 따르는 제약이 거의 없기 때문에 , 실력이 부족한 프로그래머를 보호해 주는 기능도 없다, 따라서 정상 동작하는 코드를 작성하는 것 자체가 쉽지 않으며, 그런 코드를 유지보수하는 것은 더더울 어렵다.

    2. 1일차 : 상호 배제와 메모리 모델
      • 3가지 주요한 위험 요소: 경쟁조건, 데드락, 메모리 가시성

      • 위 위험 요소를 피하는데 도움이 되는 규칙

        • 공유되는 변수에 대한 접근을 반드시 동기화 (경쟁조건)

        • 쓰는 스레드와 읽는 쓰레드가 모두 동기화 (경쟁조건 geter , setter)

        • 여러 개의 잠금장치를 미리 정해지 공통의 순서에 따라 요청

        • 잠금장치를 가진 상태에서 외부 메서드를 호출하지 않는다 

        • 잠금장치는 최대한 짧게 보유한다 (Copy)

    3. 2일차 : 내재된 잠금장치를 넘어서
      • 내재된 잠금장치의 한계  

        • 내재된 잠금장치를 얻으려고 하다가 블로킹 상태에서 빠진 스레드를 원상복귀시킬 방법이 없다

        • 내재된 잠금장치를 얻으려고 노력하는 시간을 강제로 중단시키는 타임아웃 기능이 없다.

        • 내재된 잠금장치를 얻는 방법이 하나만 존재한다 , Synchronized 블록 , Lock 블록 사용

      • 내재된 잠금장치를 극복

        • ReentrantLock , java.util.concurrent.atomic을 이용하면 

          • 잠금장치를 얻고자 기다리는 과정을 가로챌 수 있다

          • 잠금장치를 기다리는 동안 타임아웃이 발생할 수 있다

          • 잠금장치를 얻고 반납하는 동작이 임의의 순서로 일어날 수 있다.

          • 임의의 조건이 참이되는 것을 기다리기 위해 조건 변소를 사용할 수 있다.

          • 원자 변수를 이용해서 잠금장치를 사용하는 것을 피할 수 있다. 

    4. 3일차 : 거인의 어깨 위에서
      • 쓰레드를 직접 만드는 대신 스레드 풀을 이용한다. Taskpool in c# 

      • CopyonWriteArrayList in java , SynchronizedCollection in c#

      • blocking Queue , 생산자 , 소비자 / System.Collections.Concurrent.ConcurrentQueue in C#

      • ConcurrentHashMap을 이용해 맵에 대한 동시적인 접근을 지원한다.  / ConcurrentDictionary in c#

    5. 마치며
      • 쓰레드와 잠금장치를 이용한 프로그래밍

        • 분류1 : 올바르게 사용하는 것이 너무나 어렵게 느껴지기 때문에 사용을 회피, 멀티 스레드 코드를 작성하는 것을 원치 않음

        • 분류2 : 몇 개의 간단한 규칙만 지켜지면 충분하고, 그렇게 하는 것이야 말로 다른 어떤 형태의 프로그래밍과 다를 바 없다고 여긴다. 

      • 장점  - 기계 자체에 가깝기 떄문에 정확하게 사용되면 매우 효율적일 수 있다.

      • 단점 -  병렬성을 지원하지 않는다.  C# task로 작성된 코드는 병렬성을 지원?  , 어렵다. 

      • 방 안의 코끼리 - 멀티스레딩 프로그래밍을 어렵게 만드는 것은 코드를 작성하는 것이 어려운 것이 아니라 테스트하는 것이 어렵기 떄문이다. 

  3. 함수형 프로그래밍 - 

    1. 문제가 있으면 멈추는 것이 상책이다.
      • 값이 변하지 않는 데이타는 잠금장치가 없어도 여러 개의 스레드가 언전하게 접근할 수 있다.

      • 자바 같은 언어에서는 가변상태를 마드는 것이 너무 쉽다는 게 문제다, 코드가 그런식으로 작성되면 그걸 알아채는 것이 사실상 불가능에 가깝다는 것은 더 큰 문제다. 

    2. 1일차 : 가변 상태없이 프로그래밍하기
    3. 2일차 : 함수 병렬화
    4. 3일차 : 함수 동시성
      • 자바와 같은 명령형 언어에서는 발생하는 동작 순서가 소스 코드에 적힌 명령문의 순서와 밀접히 관련이 있다.

      • 함수형 언어는 선언적인 느낌이 훨씬 강하다. 어떤 연산을 어떻게 수행하는 방법을 일일이 적는 대시, 결과가 무엇이 되어야 하는지를 적는 것이다. 계산 순서를 정하는 것이 유동적이며, 함수의 코드의 병렬화가 쉽다. 

      • 참조 투명성- 함수에 대한 호출을 그것이 리턴한느 값으로 바꾸어도 프로그램의 동작에는 아무 차이가 없다. (+ 1 (+ 2 3 ))  == (+1 5

    5. 마치며 
  4. 클로저 방식 - 아이덴티티를 상태에서 분리하기

    1. 두 세계의 장점
    2. 1일차 : 원자의 영속적인 자료구조
    3. 2일차 : 에이전트와 소프트웨어 트랜잭션 메모리
    4. 3일차 : 자세히
    5. 마치며
    6.  
  5. 액터

    1. 객체보다 더욱 객체 지향적인
    2. 1일차 : 메시지와 메일박스
    3. 2일차 : 에러 처리와 유연성
    4. 3일차 : 분산
    5. 마치며
  6. 순차 프로세스 통신

    1. 의사 소통이 모든 것이다
    2. 1일차 : 채널과 고 블록
    3. 2일차 : 여러 개의 채널과 I/O
    4. 3일차 : 클라이언트 측면의 CSP
    5. 마치며
  7. 데이터 병렬성

    1. 노트북 속에 감춰진 슈퍼 컴퓨터
    2. 1일차 : GPGPU 프로그래밍
    3. 2일차 : 다차원과 작업 그룹
    4. 3일차 : OpenCL 과 OpenGL - 데이터를 GPU에 놓기
    5. 마치며
  8. 람다 아키텍처

    1. 병렬성이 빅데이터를 가능하게 만든다
    2. 1일 차 : 맵리듀스
    3. 2일차 : 배치 계층
    4. 3일차 : 속도 계층
    5. 마치며 
  9. 마치며
    1. 어디로 나아가는가?
    2. 포함하지 않은 것들
    3. 여러분 차례다