아주 예전의 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/
'Python > 2.7 information' 카테고리의 다른 글
python 멀티프로세스 락, 등등 (0) | 2017.09.24 |
---|---|
전문가를 위한 파이썬 책에서 알아낸 것들.. (0) | 2017.07.15 |
파이썬 정규식 한글. (0) | 2017.05.12 |
비동기 처리 관련.(python 3) (0) | 2017.04.30 |
yield from, generator(yield) vs coroutine (python 3) (0) | 2017.04.26 |