본 포스트는 https://docs.python.org/3.4/library/multiprocessing.html를 참고하여 작성되었음.
1. Introduction
파이썬은 GIL을 사용해 멀트쓰레딩의 효율이 떨어진다. 따라서 이러한 제한을 우회하기 위해서 멀티프로세싱을 이용하기도 함.
2. 프로세스 생성
from multiprocessing import Process import os def f(name): print('%s\'s pid : %d' %(name, os.getpid())) if __name__ == '__main__': print('producer\'s pid :', os.getpid()) p1 = Process(target=f, args=("haru",)) p2 = Process(target=f, args=("chiha",)) p1.start() p2.start() p1.join() p2.join()
producer's pid : 16312
haru's pid : 13200
chiha's pid : 13692
당연하지만 Process(...)는 프로세스 오브젝트 선언, start()는 자식프로세스 시작.
join()의 경우 자식프로세스를 종료시키는 함수인데, 문제가 생겨 제대로 종료되지 않고 좀비가 될 때를 대비해 자식프로세스가 할 작업이 끝나면 join()을 써주는 습관을 들이는 것이 좋다.
3. 프로세스 사이의 데이터 교환
3-1. 프로세스의 독립성
기본적으로 별개의 프로세스는 각자 독립된 리소스를 가지고, 이를 공유하지 않는다. 다음 예제를 보자
import multiprocessing as mp a = 71 def f(): global a a = a+1 print(a) if __name__ == '__main__': f() mp.set_start_method('spawn') #default on windows p1 = mp.Process(target=f, args=()) p2 = mp.Process(target=f, args=()) p1.start() p2.start() p1.join() p2.join()
72
72
72
결과를 보면 자식프로세스끼리 a의 값을 공유하지 않는 것은 물론이고, 부모 프로세스에서 1을 더했던것도 반영되지 않은 초기의 상태로 상속이 되는것을 확인 할 수 있다.
이제 프로세서간에 데이터 교환이 가능하게 해주는 두 가지 방법을 살펴보자.
3-2. Queue
첫 번째 방법은 프로세스들이 공유하는 큐를 사용하는 것이다. 큐는 전형적인 FIFO방식이다.
from multiprocessing import Process, Queue def f(q, name): q.put(name) print(name, 'joined. Now', q.qsize(), 'members.') if __name__ == '__main__': q = Queue() p1 = Process(target=f, args=(q, 'Haruka')) p2 = Process(target=f, args=(q, 'Chihaya')) p1.start() p2.start() p1.join() p2.join()
Haruka joined. Now 1 members.
Chihaya joined. Now 2 members.
큐가 공유되는 것을 확인할 수 있다.
3-3. Pipe
두 번째 방법은 파이프를 이용하는 것으로, 파이프 오브젝트는 서로 연결된 한쌍의 오브젝트로 이루어지며, 한쪽에서 다른쪽으로 데이터를 보낼 수 있다.
from multiprocessing import Process, Pipe
def f(conn):
print(conn.recv())
conn.send(['Chihaya', 72, 'keut'])
conn.close()
if __name__ == '__main__':
parent_conn, child_conn = Pipe()
parent_conn.send(['amami', 'haruka', 'boss'])
p = Process(target=f, args=(child_conn,))
p.start()
print(parent_conn.recv())
p.join()
['Chihaya', 72, 'keut']
부모 프로세스에서 parent_conn을 통해 child_conn으로 데이터를 보내고, 자식프로세스 에서도 반대로 데이터를 보내는 것을 확인할 수 있다.
'ㅍㄺㄻ > python3.x' 카테고리의 다른 글
구글 대문페이지 html받아와서 저장하기 (0) | 2015.01.28 |
---|---|
파이썬 강좌 by 엑시노아 (0) | 2015.01.28 |