일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 화상영어
- 3줄정리
- 10분
- 30분
- Writing
- 읽기
- 리얼 클래스
- 월간
- 잡생각
- 매일
- English
- 사이드
- 파비최
- 운동
- Daily Challenge
- 만화도
- Problem Solving
- realclass
- 미드시청
- 링피트
- 프로젝트
- 괜찮음
- 뭐든
- 스탭퍼
- FIT XR
- 개발자
- 영어공부
- leetcode
- 쓰릴오브파이트
- 영어원서읽기
- Today
- Total
파비의 매일매일 공부기록
파이썬 동시성 프로그래밍 - #1 시작하기 본문
백엔드 실무를 하다 보면 생각보다 중요한 부분이 '동시성'에 대한 내용이다.
사용자 요청 중에는 바로바로 반영할 필요가 없으면서 데이터의 양이 많은 시나리오가 꽤 있다.
이런 경우 Task 등을 통해서 비동기로 처리를 할 수 있는데, 이때 동시성에 대한 내용을 고려해야 한다.
그리고 개인적으로 좀 궁금하기도 한 분야 중 하나다.
다중 프로세서에서 일을 한 번에 시키는 건, 그만큼 효율을 증가할 수 있는 거니 꽤나 고급 프로그래밍 중 하나일 것 같다는 생각이 들기도 한다.
어쨌든 첫 장은 동시성에 대한 기본적인 내용을 소개한다.
예전에 공부할 때 세마포어(semaphore)라는 용어를 봤었는데, 이게 수기 신호라는 뜻이라고 하고
원래는 기차 등에서 사용하는 '까치발 신호기'라고 한다. (아래 링크의 그림 참조)
이처럼 동시성의 개념은 철도와 전신 분야에서 유래되었다고 한다. 이건 아예 처음 알게 된 사실.
그리고 인물로는 알고리즘 문제풀이 때 마지막 관문 같은 '다익스트라 최단 경로 알고리즘'의 창시자(?) 다익스트라가 유명하다. 이 형은 정말 컴싸에 길이길이 남을 위인인 듯..
스레드와 멀티스레드에 대해서도 설명한다.
내가 알고 있는 지식은 하나의 프로세스 안에 여러 개의 스레드가 있을 수 있고, 그 스레드를 한 번에 다중 사용하는 걸 멀티스레드라고 알고 있었다. 책의 정의는 다음과 같다.
스레드
- 운영체제에서 작동되는 스케줄링될 수 있는 인스트럭션(instruction)의 순차적인 흐름.
- 일반적으로 프로세스에 속해 있으며 프로그램 카운터, 스택, 레지스터를 비롯해 식별자로 구성
- 스레드는 프로세서가 시간을 할당할 수 있는 최소 단위의 실행
- 공유 자원 사이에서 상호작용이 가능. 다수의 스레드끼리 통신도 가능. 메모리 공유도 가능
- 메모리 주소에서 읽기 및 쓰기도 가능하지만 2개의 스레드가 메모리를 공유하고 스레드의 실행 순서가 따로 정의되지 않았을 경우 이상한 값이 도출되거나 시스템 충돌 문제를 일으킬 수 있다. 이에 관련된 용어는 레이스 컨디션(race condition, 경합 조건)이다.
- 사용자 레벨 스레드 : 다양한 작업에서 생성, 실행, 종료가 이뤄지는 스레드
- 커널 레벨 스레드 : 운영체제의 하위 레벨에서 실행되는 스레드
멀티스레딩
- 단일 스레드는 한 사람이 모든 작업을 차례대로 처리한다고 보면 되는데, 작업자가 특정 작업에 어려움이 있으면 더 이상 다른 작업을 진행할 수 없게 된다.
- 멀티스레딩에서는 한 명의 작업자가 시간을 쪼개서 여러 작업을 진행하는 멀티 테스커가 된다고 보면 된다. 특정 작업을 하다가 막힐 경우 콘텍스트를 바꿔 다른 작업을 진행할 수 있다.
- 스레딩의 장점 : 다수의 스레드는 연산은 간단하나 입출력이 많을 때 속도가 떨어지는 현상이 발생할 때 속도를 획기적으로 높여줄 수 있다. 프로세서와 비교했을 때, 메모리를 조금 차지한다. 자원을 공유하므로 스레드 간 통신이 쉽다.
- 스레딩의 단점 : CPython 스레드는 GIL(Global Interpreter Lock, 한 번에 하나의 스레드만 수행할 수 있는 락)로 인해 사용에 제약이 따른다. 스레드 간의 통신은 쉬워졌으나 레이스 컨디션이 발생하지 않도록 주의해서 코드를 작성해야 한다. 다수의 스레드 간에 컨텍스트를 바꾸는 데 수많은 계산이 필요하다. 다수의 스레드를 추가하면 전반적인 프로그램 성능은 저하될 수 있다.
프로세스
- 프로세스는 스레드가 할 수 있는 거의 모든 것이 가능. 게다가 단일 CPU 코어에 국한되지 않음.
- 하나의 주 스레드만 가지고 있을 수도 있고 여러개의 스레드를 갖고 있을 수도 있음. 각 스레드마다 레지스터와 스택이 따로 구성
- 더 많은 성능 필요 시 실행 속도를 높일 수 있으나 크로스 프로세스 통신과 관련된 문제가 발생할 수 있고 프로세스 간 통신(IPC)에서 시간을 낭비해 성능이 저하되지 않도록 유의해야 함.
- GIL의 한계를 피할 수 있으며 프로세스의 충돌은 전체 프로그램에 영향을 주지 않음
멀티프로세싱
- 파이썬의 멀티프로세싱 모듈을 사용하면 모든 코어와 CPU 사용 가능.
- GIL이 CPython에서 문제되는 부분을 피할 수 있음
- 공유 상태가 없고 통신이 부족하다는 본질적 문제 존재. 통신을 위해 IPC 형태를 사용할 경우 성능에 영향 미칠 수 있음
- 내부적 레이스 컨디션에 신경을 쓰지 않아도 됨
이벤트 기반 프로그래밍
- 어떤 이벤트(동작, 마우스 클릭 등)이 발생했을 경우 관련 부분을 실행하는 형태의 메커니즘
- 이벤트를 발생시키는 이벤트 이미터가 있으며 이벤트 루프는 이벤트를 가져와서 미리 정의된 이벤트 핸들러와 매칭
- 콜백은 비동기 방식의 프로그램에서 사용됨
반응형 프로그래밍
- RxPY : 옵서버 패턴, 반복자 패턴, 함수형 프로그래밍의 결합. 예제를 실행하려면 rx==1.6.1버전으로 해야 정상 동작함.
GPU 프로그래밍
- GPU는 일반적으로 수백만 연산을 병렬로 하는 작업에 매우 좋은 성능을 보임
- CPU는 데스크의 컨텍스트를 빠른 속도로 바꿀 수 있도록 디자인됨.
- 고성능의 그래픽 카드를 그래픽 프로그래밍에 활용하려면 PyCUDA(Nvidia 계열), OpenCL(범용), Theano(C로 구현)을 사용
파이썬의 한계 : GIL
- GIL(Global Interpreter Lock) : 병렬 파이썬 코드를 실행할 때 여러 스레드의 사용을 제한하는 상호 배제 락(mutual exclusion lock)
- 한 번에 1개의 스레드만 유지하는 락으로 스레드를 자체 코드에서 실행하려면 일단 락을 먼저 점검해야 함. 그러므로 락이 되어 있는 동안에는 다른 모든 실행은 불가
- 무작위 라운드 로빈 방식으로 작업을 배치하므로, 어떤 스레드가 락은 먼저 점유할지 파악 불가
- GIL을 제거하려는 노력은 몇 번 있었으나 안정적인 스레드를 보장하는 락을 추가하면 2배 이상의 성능 감소로 이어지게 되어 아직 다른 대안은 없다.
- 아예 GIL을 사용하지 않는 라이브러리도 존재한다.
- Jython은 자파 플랫폼에서 작동 가능한 파이썬 형태, IronPython은 닷넷 프레임워크의 상위에서 동작하여 닷넷 애플리케이션을 보완하는 방식으로 사용 가능
이후에는 동시에 그림 다운로드하기, 멀티프로세싱으로 소수 찾기에 대한 예제가 소개된다.
'Study > Python' 카테고리의 다른 글
파이썬 동시성 프로그래밍 - #3 스레드 라이프 (0) | 2021.08.10 |
---|---|
파이썬 동시성 프로그래밍 - #2 병렬화 (0) | 2021.08.09 |
깔끔한 파이썬 탄탄한 백엔드 - #12 더 좋은 백엔드 개발자가 되기 위해.. (0) | 2021.08.07 |
깔끔한 파이썬 탄탄한 백엔드 - #11 파일 업로드 엔드포인트 (0) | 2021.08.06 |
깔끔한 파이썬 탄탄한 백엔드 - #10 API 아키텍처 (0) | 2021.08.05 |