w2_sharing_queue - steelbear/HMG_Softeer_DE GitHub Wiki
멀티 프로세싱 환경에서 Queue 공유하기
멀티 프로세싱에서 중요한 부분 중 하나는 프로세스 간 데이터 공유가 올바르게 이루어져야 한다.
파이썬의 경우에도 multiprocessing
라이브러리릉 통해 자식 프로세스를 생성하고 데이터 공유를 할 수 있도록 다양한 클래스와 함수를 지원한다.
하지만 multiprocessing.Queue
를 무작정 공유하게 되면 다음과 같은 문제가 발생한다.
from multiprocessing import Queue, Pool
if __name__ == '__main__':
tasks_to_accomplish = Queue()
tasks_that_are_done = Queue()
for i in range(10):
tasks_to_accomplish.put(i)
print(f"Task no {str(i)}")
with Pool(4) as p:
p.starmap(work, [(i, tasks_to_accomplish, tasks_that_are_done) for i in range(4)])
| RuntimeError: Queue objects should only be shared between processes through inheritance
간단히 말하자면, 데이터를 공유하는 객체에 자식 프로세스가 직접 접근하면 안된다는 뜻이다. 이를 위해 우리는 Manager
를 사용해야 한다.
from multiprocessing import Manager, Pool
if __name__ == '__main__':
with Manager() as manager:
tasks_to_accomplish = manager.Queue()
tasks_that_are_done = manager.Queue()
for i in range(10):
tasks_to_accomplish.put(i)
print(f"Task no {str(i)}")
with Pool(NUM_WORKERS) as p:
p.starmap(work, [(i, tasks_to_accomplish, tasks_that_are_done) for i in range(NUM_WORKERS)])
다음과 같이 하면 manager.Queue()
를 통해 공유 메모리 객체를 생성할 수 있다. 다만 직접 multiprocessing.Queue
를 인스턴스화하는 것과는 달리, 원본 객체에 요청을 넣을 수 있는 프록시(Proxy) 객체가 나오게 된다. 이를 통해 각 자식프로세스는 직접 공유 메모리 객체에 접근하지 않고 공유 데이터를 읽고 쓸 수 있다.