Python

파이썬 SharedMemory 사용법 (mp.Value 와의 차이)

팁택토 2025. 6. 3. 15:11

파이썬에서 shared memory 사용법을 알아보자. 

참고로 서로 다른 프로세스 사이에 데이터를 전송하는 방법은 queue, pipe, shared memory 등이 있는데, 

이 중에 shared memory가 가장 성능이 좋다. 

다만 Lock 등을 잘 써야하는 단점이 있다. 

 

파이썬에서 shared_memory는 multiprocessing.shared_memory 모듈을 통해 프로세스 간 데이터를 메모리를 통해 빠르게 공유할 수 있는 기능이다. Python 3.8 이상부터 기본 제공된다. 

 

기본 개념은 아래와 같다. 

 

  • SharedMemory 객체를 생성해서 이름 기반으로 프로세스 간 공유
  • numpy.ndarray나 byte buffer를 메모리에서 공유 가능
  • 다른 프로세스는 이름으로 attach

주요 클래스와 함수는 아래와 같다. 

 

  • multiprocessing.shared_memory.SharedMemory
  • multiprocessing.shared_memory.ShareableList
  • multiprocessing.shared_memory.SharedMemoryManager (컨텍스트 매니저 지원)

사용 예시는 아래와 같다. 

1) SharedMemory로 numpy 배열 공유

from multiprocessing import shared_memory
import numpy as np

# 원본 데이터 생성
a = np.array([1, 2, 3, 4, 5])

# 공유 메모리 생성
shm = shared_memory.SharedMemory(create=True, size=a.nbytes)

# 공유 메모리를 numpy 배열로 매핑
b = np.ndarray(a.shape, dtype=a.dtype, buffer=shm.buf)

# 데이터 복사
b[:] = a[:]

# 다른 프로세스에서는 shm.name을 사용해 접근 가능
print(f"Shared memory name: {shm.name}")

# 사용 후 정리
shm.close()
shm.unlink()  # 마지막 프로세스에서 해제

 

2) ShareableList로 Python 리스트 공유

from multiprocessing import shared_memory

from multiprocessing.shared_memory import ShareableList

# ShareableList 생성
sl = ShareableList([1, 2, 3, 'hello'])

print(sl[3])  # 'hello'

# 이름으로 다른 프로세스에서 attach 가능
print(sl.shm.name)

# 정리
sl.shm.close()
sl.shm.unlink()

 

 

 

3) SharedMemoryManager로 리소스 자동 관리

from multiprocessing import shared_memory
from multiprocessing.managers import SharedMemoryManager
import numpy as np

with SharedMemoryManager() as smm:
    shm = smm.SharedMemory(size=1024)
    array = np.ndarray((256,), dtype=np.int32, buffer=shm.buf)
    array[:] = np.arange(256)

    print(array[10])  # 확인

# with 블록 종료 시 자동 unlink 및 close

 

주요 메서드 및 속성은 아래와 같다. 

 

  • SharedMemory(create=True/False, size, name=None)
  • .buf : 버퍼에 접근
  • .name : 공유 메모리 이름
  • .close() : 현재 프로세스의 공유메모리 연결 해제
  • .unlink() : 공유메모리 자체를 OS에서 삭제

주의할 점은... 

 

  • 메모리 크기를 미리 할당해야 함
  • unlink()는 모든 프로세스가 사용을 끝낸 후 호출
  • Windows에서는 다른 프로세스 attach 시 name만 필요
  • 여러 프로세스에서 동시에 쓰는 경우에는 락(lock)을 직접 구현해주어야 함

그런데, 자세히 보면 SharedMemory와 SharedMemoryManager가 따로 있다. 

이 둘의 차이는 무엇인지 확인해보자. 

SharedMemory

먼저, SharedMemory는 단일 공유 메모리 블록을 직접 생성하고 관리할 때 사용하는 클래스이다. 

📖 특징

  • 메모리 블록을 직접 생성 (create=True)
  • 생성한 메모리의 이름을 통해 다른 프로세스에서 attach 가능
  • 메모리의 해제(close() + unlink())도 직접 처리
  • numpy 배열이나 byte 버퍼 형태로 활용 가능

📌 언제 쓰냐?

  • 공유할 메모리 블록이 몇 개 없고, 직접 메모리를 열고 닫는 작업을 관리해도 괜찮을 때
  • 단순하게 한두 개의 데이터 블록을 공유할 때

SharedMemoryManager

그 다음으로 SharedMemoryManager는 여러 개의 SharedMemory 블록이나 ShareableList를 효율적으로 관리하는 컨텍스트 매니저이다. 

📖 특징

  • 컨텍스트 매니저(with)로 자원 관리를 자동으로 처리
  • 내부적으로 SharedMemory와 ShareableList를 쉽게 생성하고 관리 가능
  • with 블록이 끝나면 자동으로 close 및 unlink 처리

📌 언제 쓰냐?

  • 공유 메모리 블록이 여러 개이거나, 여러 개의 ShareableList를 편하게 관리하고 싶을 때
  • 프로세스 풀이나 병렬 처리 환경에서 리소스 누수 걱정 없이 공유 메모리를 쓸 때

즉, SharedMemory는 그냥 단순히 단일 메모리 블록을 할당할 때 사용하고, 

SharedMemoryManager는 shared memory를 여러개 관리할 때, 자동으로 관리하고자 할 때 사용한다. 

 

결론적으로는... 

 

  • 간단하게 공유 메모리 1~2개 쓸 거면 SharedMemory
  • 여러 개를 쓴다거나 프로세스 풀/병렬 환경에서 리소스 누수 없이 관리하고 싶다면 SharedMemoryManager

그런데 multiprocessing 을 보다보면, mutiprocessing.Value 가 있고, 이것을 통해 프로세스간에 데이터 공유가 가능하다고 한다. SharedMemory랑 Value랑 차이는 뭔가? 

 

📌 multiprocessing.Value는 SharedMemory 기반이 아님

multiprocessing.Value는 프로세스 간에 단일 값(숫자, 문자 등)을 공유하기 위한 객체
내부적으로 ctypes를 이용한 shared object로 구현돼 있고,
Python 3.8부터 도입된 multiprocessing.shared_memory 모듈의 SharedMemory와는 전혀 다른 방식임

📌 Value의 내부 동작

  • POSIX에서는 mmap 또는 anonymous shared memory
  • Windows에서는 named shared memory
  • Python 3.8 이상이더라도 shared_memory.SharedMemory를 사용하지 않음
  • 자원을 직접 close()/unlink() 할 필요 없이 프로세스가 끝날 때 자동 정리

그리고 Value 자체에 Lock 옵션이 내장되어 있어 동시 접근 제어도 가능

 

오, Value 자체에는 Lock 이 내장되어 있어, 동시 접근 제어도 가능하다는 것은 편리한 기능이 될 수 있다. 

 

📌 Value vs SharedMemory

항목 multiprocessing.Value SharedMemory
데이터 크기 int, float, char 등 단일 값 numpy array, byte buffer 등 대용량
메모리 관리 프로세스가 끝나면 자동 정리 직접 close(), unlink() 호출 필요
Lock 지원 내장 (옵션) 없음 (직접 Lock 관리 필요)
구현 방식 ctypes 기반 shared object Python 3.8+ multiprocessing.shared_memory
SharedMemoryManager 사용 여부 X 필요 시 가능

정리해보면 아래와 같다. 

 

  • Value는 SharedMemory도 아니고 SharedMemoryManager도 아님
  • 자체적으로 ctypes 기반의 shared object 구현
  • 작은 단일 값 공유 시 가장 간편
  • Lock 내장

그래서 결국 최종적으로는 이렇게 정리 될 수 있다. 

상황 추천 방법

상황 추천방법
숫자 1~2개 공유 + 동기화 필요 multiprocessing.Value
리스트 형태 공유 + 동기화 필요 multiprocessing.Array
numpy 배열, 대용량 데이터 공유 SharedMemory + Lock 직접
여러 공유 메모리/ShareableList 관리 SharedMemoryManager