왜 multiprocessing 존재
GIL 이 두 스레드가 Python 바이트코드 병렬 실행 막음. Multiprocessing 이 별 Python 프로세스 사용해서 우회 — 각자 자기 GIL, 자기 메모리, 자기 모든 거. 진짜 병렬화 원하는 CPU 바운드 작업엔 이게 답.
비용 — 프로세스 시작 + 직렬화
프로세스 시작이 스레드 시작보다 훨씬 느림 (밀리초 vs 마이크로초). 프로세스 간 데이터 전달엔 *직렬화* 필요 — Python 객체가 경계 통과 시 pickle/unpickle. 그래서 multiprocessing 이 task 당 작업이 시작 + 통신 오버헤드보다 클 때 이김. 1 초 계산엔 오버헤드 무시 가능. 1ms task 엔 threading 또는 동시성 X 가 빠름.
ProcessPoolExecutor — 쉬운 길
concurrent.futures.ProcessPoolExecutor 가 ThreadPoolExecutor 와 같은 API. 그냥 클래스 swap. 함수와 인자가 picklable 해야 — top level 에 정의 (다른 함수 안 X), 인자가 표준 타입 (lambda X, 파일 핸들 X 등). 첫 시도에 사람들 잡힘.
state 공유 — Manager 와 shared memory
프로세스가 디폴트로 메모리 공유 X. multiprocessing.Manager 가 프로세스 간 작동하는 공유 list/dict 의 proxy 줘 (오버헤드 있음). multiprocessing.shared_memory (3.8+) 가 고처리량 숫자 데이터 위한 raw shared memory 블록. 대부분 multiprocessing 코드는 이거 안 필요 — 인자 in, 결과 out, 공유 state X.