2016-08-09 1 views
0

아래 예제에서 멀티 프로세싱을 사용할 때 n을 어떻게 늘릴 수 있습니까? [k.n for k in klasses]가 예상대로 [0, 0, 0, 0]를 생산 실행병렬로 여러 클래스의 클래스 메서드를 실행할 때 클래스 상태를 유지하는 방법은 무엇입니까?

class Test: 
    def __init__(self, n): 
     self.n = n 

    def run(self): 
     self.n += 1 
     return True 

# Generate 4 classes 
klasses = [Test(0) for i in range(4)] 

. 사용하여 병렬로 각 클래스의 기능 run()를 실행하려고

: 예상대로

from multiprocessing import Pool  
with Pool() as pool: 
    results = [pool.apply_async(k.run,()) for k in klasses ] 
    result = [i.get() for i in results] 

결과 result에서는 [True, True, True, True]를 반환. [k.n for k in klasses] 결과가 [0, 0, 0, 0]이 되어도 클래스 'n'속성은 변경되지 않았습니다. 방법이 병렬로 처리되지 않는 경우. [k.run() for k in klasses], [k.n for k in klasses]은 예상대로 [1, 1, 1, 1]을 반환합니다.

클래스가 병렬로 실행될 때 상태를 유지할 수있는 방법이 있습니까?

답변

1

각 작업자가 별도의 프로세스이므로 multiprocessing의 공유 상태를 명시 적으로 수행해야합니다. multiprocessing docs cover the various options in so detail. 가장 간단한 해결책은 nmultiprocessing.Value으로 만드는 것이지만, 적절한 유형 및 특성을 사용하도록 Test 클래스를 크게 변경해야합니다.

또는 pool.imap/pool.imap_unordered을 사용하여 작업을 수행하는 방법을 찾고 상태가 인수로 전달되고 새 데이터가 반환됩니다. 이런 식으로 문제를 표현할 수 있다면 라이브 상태가 아닌 입력 및 출력으로 공유를 제한하는 것이 더 좋습니다.

+0

응답 해 주셔서 감사합니다. 'multiprocessing.Value'는 자식 프로세스 사이에 공유 상태가 아닌가? 위의 예에서 하위 프로세스 간에는 공유가 필요하지 않습니다. 즉, 'n'은 클래스마다 다를 수 있습니다. 주요 관심사는 부모 프로세스의 클래스가 각 메소드 호출이 (모든 자식 프로세스의 클래스 상태로) 변경 한 내용을 반영하지 않는다는 것입니다. – Greg

+0

@Dave : 부모와 자식 간의 공유 상태는 모든 자식과 공유하는 데 필요한 것과 동일한 메커니즘을 사용합니다. 기능적 디자인 (대신에 새로운'Test's를 돌려주고 대신)을 사용하고'pool.map' /'imap' /'imap_unordered'를 사용하면 부모의 상태를 새로 계산 된 상태로 바꿀 수 있습니다. 아이,하지만 그것은 직접적인 공유가 아닙니다; '다중 처리 (multiprocessing) '는 근로자들간에 송수신되는 모든 데이터에 대해 산정 (pickling)과 언 피클 링 (unpickling)을하는 것이다. – ShadowRanger

+0

완벽하게 이해합니다. 감사합니다! – Greg

관련 문제