Python/2.7 information

multiprocessing에서 여러 프로세스가 동시 변수 참조하는 문제

qkqhxla1 2017. 5. 29. 12:28

아주 예전의 http://qkqhxla1.tistory.com/15 포스팅에서 언급했듯이 여러개의 쓰레드나 프로세스에서 한 데이터에 그냥 접근하면 문제가 생긴다. 오늘 프로그래밍을 하는데, 멀티프로세싱으로 여러개의 데이터를 동시에 한 리스트에 넣는 프로그램을 짰었다. 멀티프로세싱으로 동시에 한 값을 바꾸는건 문제가 되는걸 알고있었는데, 집어넣는게 문제가 될줄은 몰랐다. 

바빠서 왜 이게 문제가 되는지는 아직 찾아보지 못했는데, print로 출력해 본 결과 글로벌한 리스트 하나에 값이 들어가는게 아니라 프로세스마다 각각의 리스트가 있어서 각각의 리스트에 들어가는것처럼 출력이 되었다. 

그리고 아래 글은 그 이후에 삽질한 일부 내용을 정리한 글이다.


첫번째로 세마포어를 찾아보려고 하였다. 위의 포스팅의 쓰레드 예처럼 값을 append하기전에 세마포어를 얻어오고, 값을 넣은후에 풀어주면 될것같다는 생각이 들었다. 그래서 이것저것 찾아봤는데

docs페이지에 (https://docs.python.org/2/library/multiprocessing.html) 세마포어 말고도 lock이란게 있었다. 찾아보니 lock이 원래의 락 개념이고, 세마포어가 락을 감싼 wrapper라고 한다.

https://stackoverflow.com/questions/21665657/python-binary-semaphore-vs-lock


어쨌든 append전에 lock을 가져오고, 후에 풀어줬는데 잘 되질 않았다.(동일한 문제 발생) 또 찾아보다가

multiprocessing 전용 자료구조가 정의된 Manager라는걸 발견해서 거기서 리스트를 가져다가 썼다.

http://www.programcreek.com/python/example/8456/multiprocessing.Manager (위의 multiprocessing 공식 홈페이지 내에도 설명이 잘 되어있다.)


from multiprocessing import Process, Manager

....

self.mylist = Manager().list()


처럼 쓰면 되고 아직 원리를 들여다보지는 못했는데 저 리스트에 값을 추가하거나 제거할때 락이나 세마포어같은걸 가져오지 않아도 잘 처리가 된다. 일단 더 알게 되면 추가.


--------------------------------------------------------------

이유를 몰랐었는데 댓글로 어떤분이 일깨워 주셨었다. 

이번 삽질의 가장 큰 원인은.. 쓰레드는 메모리를 공유하지만 프로세스는 각각의 메모리 공간을 갖는다 였다. 시험에도 나왔었고, 취업하기전에 단골 면접질문이라고 중요하다고 외웠던게 기억나는데 기억을 못했던게 부끄럽다.


더 읽기.

http://blog.naver.com/cmw1728/220475925494

https://stackoverflow.com/questions/200469/what-is-the-difference-between-a-process-and-a-thread


또 ipc란 뭔지에 관한 글.

http://whatis.techtarget.com/definition/interprocess-communication-IPC


위에서 우연히 검색으로 찾은 Manager는 ipc기반으로 구현된 거라고 하긴 한데 프록시를 사용한다고 한다... 뭔가 간단히 하려다가 더 복잡해졌다. 

Manager에 대한 글이다. 심심하면 읽어보자.

https://dustinoprea.com/2013/11/19/manager-namespaces-for-ipc-between-python-process-pools/