파비의 매일매일 공부기록

파이썬 동시성 프로그래밍 - #8 멀티프로세싱 본문

Study/Python

파이썬 동시성 프로그래밍 - #8 멀티프로세싱

fabichoi 2021. 8. 15. 23:30

이번장은 멀티프로세싱과 병렬화 실행이 어떻게 수행되는지 알아본다.

 

GIL 작업 : 전역 인터 프린터 락(GIL)은 CPU 기반 작업에서 성능을 저해하는 메커니즘 임. 멀티프로세싱을 이용하여 여러 GIL 인스턴스를 활용해 프로그램에서 한 스레드의 바이트코드를 실행하는 데 있어 한번에 정제화 할 필요가 없으며 CPU 처리 능력을 최대로 활용할 수 있게 해 줌.

- 하위 프로세스 활용하기 : 파이썬에서는 CPU의 독립적인 코어에서 실행 가능한 여러 프로세스를 실행 가능.

 

프로세스 라이프 : 멀티프로세싱 모듈에는 파이썬 프로그램 내에서 프로세스를 시작하는 3가지 메서드가 있다. (spawn, fork, forkserver)

- fork를 사용해 프로세스 시작 : forking이란 부모 프로세스에서 자식 프로세스를 생성하기 위해 유닉스 시스템에서 사용되는 메커니즘. 자식 프로세스는 실제 현실처럼 부모 프로세스와 동일하게 부모의 모든 자원 상속 받음

- 프로세스 스폰 : 개별적인 프로세스를 스폰(spawn)함으로써 그 밖의 파이썬 인터프리터 프로세스를 실행할 수 있음. 자체 전역 인터프리터 락이 포함되며 각 프로세스는 병렬로 실행 가능. 더 이상 전역 인터 프린터 락의 한계에 대해 신경 쓸 필요 없음. 새로 스폰된 프로세스는 해당 실행 메서드에 어떤 인자든 실행하기 위해 필요한 자원만 상속 받음. 

- forkserver : 서버가 인스턴스화 됨. 그 후 프로세스를 생성하는 모든 요청을 다루며, 파이썬에서 새로운 프로세스를 생성하려면 새로 인스턴스화 된 서버에 요청을 전달. 그러면 해당 서버는 프로세스를 생성하고 프로그램에서 자유롭게 사용 가능.

- 데몬 프로세스 : 데몬 플래그를 참으로 설정해 시행 중인 프로세스를 데몬화 할 수 있음. 데몬 프로세스는 메인 스레드가 실행되는 동안 계속되며 실행이 끝나거나 메인 프로그램이 종료될 때만 종료됨.

- PID를 이용해 프로세스 확인 : 운영체제에 있는 모든 프로세스는 프로세스 확인자를 구성하는데, 일반적으로 PID라고 불림. 파이썬 프로그램 내에서 멀티 프로세스 동작 시, 프로그램에서 오직 1개의 PID만 있을 거라고 생각하지만 그렇지 않음. 파이썬 프로그램 상에서 스폰하는 각 하위 프로세스가 운영체제 내에서 개별적으로 확인하고자 자체 PID 수를 받음. 자체 할당된 PID가 있는 개별적인 프로세스는 로깅 및 디버깅 같은 작업을 수행할 경우 유용.

- 프로세스 종료 : 실행 중인 자식 프로세스를 종료하는 경우, 로컬 상의 ad hoc을 실행하는 파이썬 코드에서는 크게 중요하지 않지만 방대한 서버를 다루는 기업용 파이썬 프로그램에서는 매우 중요함. 오랜 기간 실행되는 시스템에서 수천, 수만의 프로세스를 실행할 수는 없으며 일반적으로 시스템 자원에 그대로 남겨둘 수도 없음. 그러므로 프로세스를 종료하는 일은 중요함.

- 현재 프로세스 얻기 : 개별적인 프로세스를 확인할 수 있는 것은 로깅 및 디버깅의 관점에서 중요하므로 파이썬 프로그램상의 모든 프로세스 PID를 검색 가능해야 함. 이는 멀티스레딩에서 현재 스레드를 검색하는 방법을 살펴본 부분과 동일하게 해 볼 수 있음.

- 프로세스를 하위 클래스화 : 지난 3장에서 threading.Thread 클래스를 하위 클래스화 해서 스레드를 생성하는 방법을 살펴봤는데, 이와 동일하게 프로세스를 생성하는데도 사용 가능한 방법을 소개.

 

멀티프로세싱 풀 : 멀티프로세싱 모듈 내에서 다양한 기능을 가진 Pool 클래스를 활용할 수 있음. Pool 클래스는 프로그램 내의 여러 자식 프로세스를 쉽게 실행하고 풀에서 작업자를 선택 가능. concurrent.futures.ProcessPoolExecutor와 Pool의 차이, 콘텍스트 관리자에 대해, 프로세스 풀에 작업 전달하는 방법에 대해 예제를 통해 소개한다.

 

프로세스 간 통신 : 수많은 하위 프로세스 간 동기화에 있어 다양하게 활용 가능한 선택사항이 있다. (큐, 파이프, 매니저, ctype) 4개의 옵션은 멀티 프로세스 애플리케이션에 활용 가능한 다양한 통신 메커니즘을 보여준다. 통신에 관련된 선택을 할 때, 한 주제에 몰두해 시간을 보내보는 것도 추천.

- 파이프 : 한 프로세스에서 그 외 프로세스로 정보를 전달하는 방법. 익명 파이프/기명 파이프 존재. 운영체제에서 자체 프로세스 간에 정보를 전달하기 위한 가장 일반적인 메커니즘이므로 멀티 프로세스 프로그램의 작업에 동일하게 적용 가능. 기명 파이프는 운영체제가 끝날 때까지 존재하며 나머지는 익명 파이프와 동일. 익명 파이프는 한 번에 한 방향으로만 통신 가능. 이중 통신을 위해서는 2개의 익명 파이프로 프로세스 간 통신을 하며 운영체제에 의해 관리되고 고성능 프로세스 통신에 이용됨.

- 파이프로 작업하기 및 예외 처리하기(os 모듈 사용 or multiprocessing.Pipe() 활용)에 대한 예를 소개한다.

 

multiprocessing.Manager : 파이썬 객체를 조절하고 프로그램에서 안전한 스레드와 프로세스를 제공. manager 객체로 여러 프로세스 간에 리스트나 딕셔너리 같은 데이터를 공유 가능하며 일반적으로 자체 통신을 구현하는 첫 관문임.

- 네임스페이스 : 호출할 수 있는 퍼블릭 메서드는 없고 쓰기가 가능한 애트리뷰트에서는 유용하게 사용됨. 멀티 프로세스 간에 몇 개의 애트리뷰트를 공유하는 빠른 방법이 필요할 때는 네임스페이스가 최고의 방법.

- 큐 : 큐 동기화와 관련된 내용

- Listener와 Client 클래스 : multiprocessing.connection 모듈을 활용한 예제 소개.

- 로깅 : 로깅이 어떻게 구현되는지 살펴볼 필요 있음. 어려운 문제에 직면했을 때, 프로그램 출력을 로깅하는 문제에 있어 더 나은 방법 필요. 앱에서 잘 구성된 로깅 시스템을 구현하는 것은 차후에 프로그램의 특성을 이해하는 좋은 방법이 됨.

 

순차적인 프로세스 통신 : 순차적인 프로세스(CSP)는 여러 개의 동시성 모델이 각자 어떻게 상호작용을 하는지 보여줌. 일반적으로 여러 개의 동시성 프로세스 간에 메시지를 전달하는 채널을 주로 사용하며 내부는 클로저 및 Go 언어로 이뤄져 있음.

- PyCSP : CSP 기반 핵심 프리미티브로 구현된 파이썬 라이브러리. 기본적인 파이썬 모듈로 동작되는 쉬운 분산 통신 모델을 제공. 전반적으로 파이썬 내장 데코레이터를 사용한 멀티 프로세스 기반 파이썬 앱 구현에 대한 예제를 들어 설명.

 

어렵다. 이 책은 다음 챕터로 갈수록 어려워지는 듯.

그래도 몇 개의 용어(파이프 등)에 대한 내용은 이해할 수 있어서 다행.

반응형
Comments