개요
- 초기 구상은 프로그램이 실행될때 여러 자식 프로세스를 생성함 → 멀티 프로세싱 라이브러리
- 이는 GIL을 회피하여 성능 향상을 꾀하기 위함 이었음
- 독립적인 서비스, 관심사 분리
- 그러나 프로세스간 데이터 교환이 필요함을 인지
- 이를 해결하기 위한 방법 모색
- MultiProcess Queue(Lock), Redis, Http, RawArray 여러가지 방법을 시도함
- 그중 RawArray가 가장 속도가 빨랐음
이론적으로 상상한 RawArray
- 최초 프로그램이 구동될때 공유 메모리 배열을 선언하고 이에 참조할수 있는 객체를 하위 프로세스로 전달함
- 나머지 프로그램은 참조한 공유 메모리 배열을 사용하니 프로세스간 데이터가 교환될것이라 예상함
- 통신 방법은 여러가지가 있겠지만 참조값을 전달하니 모든 프로세스가 같은 메모리 영역을 바라보고 있을것이라 예상
- 이는 실제로 잘 동작했음
- 그러나 궁금증.. 프로그램을 구동하면서 여러번 RawArray가 생성되는데 어떻게 같은 값인걸 알까?
실제로 동작하는 RawArray
- 최초 프로그램이 구동될때 공유 메모리 배열을 선언하고 이에 참조할수 있는 객체를 하위 프로세스로 전달함
- RawArray가 선언되면 타입과 사이즈를 검증하고 이를 0으로 초기화 한다음 공유 메모리로 생성함
- Linux: shm_open, mmap | Window: createFileMapping, MapViewOfFile 을 사용함
- os단에서 제공하는 API로 공유메모리를 설정하고 사용가능
- 공유메모리는 만드는것이 만들어진것의 영역을 가져오는것임.
- 통신 방법은 RawArray를 생성하면 참조값을 알기때문에 이걸로 접근(통신)하는거였음!
- 그럼 파이썬은 어떻게 공유 메모리가 여러번 선언되도 같은 공유 메모리 임을 아는가?
- RawArray 객체는 실제로 공유메모리의 뷰, 핸들 으로 동작함
이는 실제로 공유 메모리를 생성하는게 아니라 그냥 주소, 크기, 데이터 타입등의 메타 데이터만을 포함함
- 하위 프로세스에서 여러번 선언해도 실제로는 미리 준비되어있는 공유 메모리의 뷰 만을 생성하는것임
- 상위 프로세스에서 이미 참조값을 전달 했고 상위 프로세스에서 포크 되어 생성되기 때문에
선언되도 같은 메모리 영역을 참조 할 수있는것!
- 결론적으론 상위 프로세스에서 포크된 하위 프로세스는 부모의 메모리 공간이 복사되고
이는 동일하게 매핑됨 이후 재선언해도 메모리가 할당되는것이 아닌 참조값만 새로 만드는거라
메타 데이터를 통하여 동일하게 접근가능