실용주의 프로그래머 Day6

HYl·2022년 3월 29일
0

DAY 6

오늘 읽은 범위 : 6장 동시성


책에서 기억하고 싶은 내용을 써보세요.

동시성 (Concurrency)

  • 둘 이상의 코드 조각이 실행될 때 동시에 실행 중인 것처럼 행동하는 것이다
    • ‘병렬성 parallelism’ 이란 실제로 동시에 실행되는 것이다.
  • 파이버(fiber), 스레드, 프로세스 등을 사용하여 동시성을 구현한다.
    • 실행 중에 코드의 다른 부분으로 실행을 전환할 수 있는 환경에서 코드를 구동해야 한다.
  • 병렬성을 얻으려면 두 가지 일을 동시에 할 수 있는 하드웨어가 필요하다.
    • CPU 하나에 있는 여러 개의 코어일 수도 있고, 컴퓨터 한 대에 있는 여러 CPU이거나 아니면 네트워크로 연결된 여러 대의 컴퓨터일 수도 있다.

모든 일에 동시성이 있다

  • 시스템의 규모가 어느 정도를 넘어가면 동시성을 고려하지 않고 코드를 작성하기란 거의 불가능하다.
  • 여러분의 애플리케이션이 실제 세상을 다루기 원한다면 동시성은 필수다. 세상은 비동기적 이기 때문이다.
  • 동시성이나 병렬성을 지원하는 코드를 쓰는 건 왜 그렇게 어려울까?
    • 프로그래밍을 순차적 시스템으로 배워서다.
    • 동시에 두 가지 일이 일어날 수 있으면 골칫거리로 변해서다.
    • 가장 큰 문제는 ‘공유 상태 shared state’다.

동시성의 해결 방안 중 액터(actor) 모델 이 있다, 액터 모델에서는 프로세스들이 독립적으로 수행되며 서로 데이터를 공유하지 않는다.


시간적 결합 (temporal coupling) 깨트리기

  • 시간에는 우리가 신경 써야 할 측면이 두 가지 있는데, 동시성 (동시에 일어나는 일들)과 순서 (시간의 흐름 속에서 일들의 상대적인 위치) 다.

그렇게 함으로써 유연성도 얻을 수 있고, 작업 흐름 분석과 아키텍처, 설계, 배포와 같은 개발의 여러 측면에서 시간과 관련된 의존성도 함께 줄일 수 있다. 결과적으로 분석하기 더 쉽고 응답속도도 더 빠르며 더 안정적인 시스템을 만들 수 있을 것이다.

동시성 찾기

  • 작업 흐름 분석으로 동시성을 개선하라.
    • 활동 다이어 그램, activity diagram 같은 표기법을 사용해서 작업 흐름을 기록하는 것이 한 방법이다.
  • 활동 다이어그램을 사용하면 동시에 수행할 수 있는데도 아직 동시에 하고 있지 않은 활동들을 찾아내서 병렬성을 극대화할 수 있다.

동시 작업의 기회

  • 활동 다이어그램은 동시에 작업할 수 있는 부분들을 보여 준다. 하지만 진짜 로 동시에 하는 것이 좋은지는 알려주지 않는다.
  • 동시성을 고려한 설계 가 필요하다.

병렬 작업의 기회

  • 일반적인 형태는 커다란 작업을 독립적인 부분들로 쪼개서 병렬로 각각 처리한 다음, 결과를 합치는 것이다.
    • 이런 방식 덕분에 모든 가용 코어를 활용한 빠른 컴파일이 가능하다.

기회를 찾아 내는 것은 쉽다

동시 작업이나 병렬 작업을 해서 이득 을 볼 수 있는 부분을 찾았다. 이제 어려운 부분이 남았다. 어떻게 안전하게 구현 할 수 있을까?


공유 상태는 틀린 상태

두 프로세스같은 메모리 영역에 쓰기가 가능하다는 점이 아니다. 문제는 어느 프로세스도 자신이 보는 메모리가 일관되어 있음을 보장할 수 없다는 점

세마포어 및 다른 상호 배제 방법

  • 세마포어, semaphore는 단순히 한 번한 사람만이 가질 수 있는 무언가다.
  • 코드로 살펴보면, 전통적으로는 세마포어를 획득하는 작업을 ‘P’로, 반환하 는 작업을 ‘V’로 불렀지만,4 요즘은 ‘잠금lock/잠금 해제unlock’, ‘획득claim/반환 release’ 등으로 부른다.
case_semaphore.lock()

if display_case.pie_count > 0
	promise_pie_to_customer()
    display_case.take_pie()
	give_pie_to_customer()
end

case_semaphore.unlock()
  • 세마포어를 확보한 쪽은 평소처럼 계속 진행한다. 세마포어를 얻지 못한 쪽은 세마포어를 얻을 수 있을 때 까지 멈춰 있는다. 즉, 기다린다.

  • 여기서 문제점은 뭘까 ?

    • 가장 큰 문제는 진열장에 접근하는 모든 사람이 빠짐없이 세마포어를 사용해야만 제대로 동작한다는 것이다. 만약 누군가가 깜빡한다면, 다시 말해서 어떤 개발자가 약속을 지키지 않는 코드를 쓴다면 다시 혼돈에 빠진다.

리소스를 트랜잭션으로 관리하라

  • 현재의 설계가 미흡한 것은 진열장 사용을 보호할 책임을 진열장을 사용하는 사람에게 전가하기 때문이다.
    • 제어를 중앙 으로 집중시키자.

트랜잭션이 없는 갱신

  • 수정 가능한 리소스를 공유하는 애플리케이션 코드 어디에서나 동시성 문제가 발 생할 수 있다.
  • 불규칙한 실패는 동시성 문제인 경우가 많다.

그 밖의 독점적인 접근

  • 대부분의 언어에는 공유 리소스에 독점적으로 접근하는 것을 도와주는 라이브러리가 있다.
    • 상호 배제 ( mutual exclusion )를 의미하는 뮤텍스 ( mutex )라고 부르기도 하고, 모니터 ( monitor )나 세마포어라고 부르기도 한다.
  • 언어 자체에 동시성 지원이 들어 있는 언어도 있다.

액터와 프로세스

  • 액터프로세스를 사용하면 흥미로운 방식으로 동시성을 구현할 수 있다. 공유 메모리 접근을 동기화하느라 고생할 필요도 없다
  • 액터는 자신만의 비공개 지역 상태 (state)를 가진 독립적인 가상 처리 장치 (virtual processor) 다.
  • 프로세스는 본래 더 일반적인 가상 처리기로, 보통 운영 체제가 동시성을 지원하기 위하여 구현한다.

액터는 언제나 동시성을 띤다

공유 상태 없는 동시성을 위하여 액터를 사용하라.

  • 액터를 관리하는 것이 하나도 없다.
  • 시스템이 저장하는 상태는 오직 메시지 그리고 각 액터의 지역 상태뿐이
    다.
  • 모든 메시지는 일방향이다.
  • 액터는 각 메시지를 끝날 때까지 처리하고 중간에 다른 일을 하지 않는다. 즉, 한 번에 하나의 메시지만 처리한다.

칠판

  • 일종의 ‘자유방임주의’적 동시성이다.
  • 컴퓨터 기반의 칠판 시스템은 원래 음성 인식, 지식 기반 추론 시스템 등 해결해야 할 문제의 규모가 크고 복잡한 인공 지능 애플리케이션에서 사용되었다.
  • 이 시스템들이 실제로 성공하지는 못했다. 우리 생각에는 이런 동시 협력 처리에 대한 수요가 아직 많지 않았던 것도 실패에 한몫했을 것 같다.
  • 칠판으로 작업 흐름을 조율하라.
  • 마지막으로 이런 종류의 시스템은 맞춰야 하는 구성 요소 수가 더 많기 때 문에 배포하고 관리하기 더 까다롭다. 하지만 그 결과 시스템이 더 잘게 쪼개 지고, 전체 시스템이 아니라 개별 액터만 교체하여 시스템을 업데이트할 수 있다는 면에서 어느 정도 보상 받는다.

오늘 읽은 소감은? 떠오르는 생각을 가볍게 적어보세요.

프로세스와 스레드라는 주제로 블로그 글을 작성을 한 적이 있었는 데, 글 작성시에 동시성이라는 개념을 이해를 잘 못했었던 기억이 난다.

이 책을 읽고 난 후에, 동시성이라는 것이 프로그래밍을 할 때 매우 중요한 개념이라는 것을 체감할 수 있었고 이해할 수 있는 좋은 경험을 쌓은 것 같다.

책 도중에 자바스크립트로 동시성에 대한 코드가 잠시 나왔었는 데, 그부분도 더 공부를 해보아야겠다.

항상 프로그램을 설계할 때 동시성 개념을 유의하며 작성해야겠다. 더 나은 코드를 설계하기 위하여 끊임없는 고민과 동료들과의 협업을 통하여 규칙을 잘 설정하는 것도 매우 중요하다.

profile
꾸준히 새로운 것을 알아가는 것을 좋아합니다.

0개의 댓글