개요

  1. 초기 구상은 프로그램이 실행될때 여러 자식 프로세스를 생성함 → 멀티 프로세싱 라이브러리
  2. 이는 GIL을 회피하여 성능 향상을 꾀하기 위함 이었음
    1. 독립적인 서비스, 관심사 분리
  3. 그러나 프로세스간 데이터 교환이 필요함을 인지
    1. 이를 해결하기 위한 방법 모색
    2. MultiProcess Queue(Lock), Redis, Http, RawArray 여러가지 방법을 시도함
  4. 그중 RawArray가 가장 속도가 빨랐음

이론적으로 상상한 RawArray

  1. 최초 프로그램이 구동될때 공유 메모리 배열을 선언하고 이에 참조할수 있는 객체를 하위 프로세스로 전달함
  2. 나머지 프로그램은 참조한 공유 메모리 배열을 사용하니 프로세스간 데이터가 교환될것이라 예상함
    1. 통신 방법은 여러가지가 있겠지만 참조값을 전달하니 모든 프로세스가 같은 메모리 영역을 바라보고 있을것이라 예상
  3. 이는 실제로 잘 동작했음
  4. 그러나 궁금증.. 프로그램을 구동하면서 여러번 RawArray가 생성되는데 어떻게 같은 값인걸 알까?

실제로 동작하는 RawArray

  1. 최초 프로그램이 구동될때 공유 메모리 배열을 선언하고 이에 참조할수 있는 객체를 하위 프로세스로 전달함
    1. RawArray가 선언되면 타입과 사이즈를 검증하고 이를 0으로 초기화 한다음 공유 메모리로 생성함
    2. Linux: shm_open, mmap | Window: createFileMapping, MapViewOfFile 을 사용함
      1. os단에서 제공하는 API로 공유메모리를 설정하고 사용가능
      2. 공유메모리는 만드는것이 만들어진것의 영역을 가져오는것임.
  2. 통신 방법은 RawArray를 생성하면 참조값을 알기때문에 이걸로 접근(통신)하는거였음!
  3. 그럼 파이썬은 어떻게 공유 메모리가 여러번 선언되도 같은 공유 메모리 임을 아는가?
    1. RawArray 객체는 실제로 공유메모리의 뷰, 핸들 으로 동작함 이는 실제로 공유 메모리를 생성하는게 아니라 그냥 주소, 크기, 데이터 타입등의 메타 데이터만을 포함함
    2. 하위 프로세스에서 여러번 선언해도 실제로는 미리 준비되어있는 공유 메모리의 뷰 만을 생성하는것임
      1. 상위 프로세스에서 이미 참조값을 전달 했고 상위 프로세스에서 포크 되어 생성되기 때문에 선언되도 같은 메모리 영역을 참조 할 수있는것!
    3. 결론적으론 상위 프로세스에서 포크된 하위 프로세스는 부모의 메모리 공간이 복사되고 이는 동일하게 매핑됨 이후 재선언해도 메모리가 할당되는것이 아닌 참조값만 새로 만드는거라 메타 데이터를 통하여 동일하게 접근가능