3

작업 목록을 작업 목록에 추가하려고하는 작업자 풀을 설정하는 간단한 파이썬 다중 처리 스크립트가 있습니다. 이 스크립트에는 다음과 같은 3 개의 호출 스택이 있습니다. - 다른 함수 g1을 호출하는 여러 작업자 프로세스를 생성하는 기본 호출 f1. 스크립트가 (Windows 7/64 비트/VS 2010/PyTools에서 우발적으로) 디버깅을 시도하면 스크립트는 중첩 된 프로세스 생성 루프로 실행되어 끝없는 프로세스를 생성합니다. 누구나 이유를 판단 할 수 있습니까? 나는 아주 간단한 것을 놓치고 있다고 확신한다. 여기에 문제가있는 코드는 다음과 같습니다 -파이썬 다중 처리 관리자가 프로세스 생성 루프를 시작합니다

import multiprocessing 
import logging 

manager = multiprocessing.Manager() 
results = manager.list() 

def g1(x): 
    y = x*x 
    print "processing: y = %s" % y 
    results.append(y) 

def f1(): 
    logger = multiprocessing.log_to_stderr() 
    logger.setLevel(multiprocessing.SUBDEBUG) 

    pool = multiprocessing.Pool(processes=4) 
    for (i) in range(0,15): 
     pool.apply_async(g1, [i]) 
    pool.close() 
    pool.join() 

def main(): 
    f1() 

if __name__ == "__main__": 
    main() 

PS : 아무 소용 주에 multiprocessing.freeze_support()를 추가했습니다.

+1

확실하지,하지만 문서에'multiprocess.Manager'를 사용하는 예는 작성하는' Manager '를 차단하고 명시 적 매개 변수로 관리 자원을 작업자에게 전달합니다. 대신 그 방법을 시도 했습니까? 제 매니저의 느낌은 관리자 객체가 모듈 스코프에서 생성되었을 때 unpickling 프로세스와 관련이 있다는 것입니다 (새 관리자 스레드가 생성 될 때를 포함하여 새 스레드가 생성 될 때마다 새로운 관리자 스레드가 생성되는 것과 같은 것) , 따라서 무한 재귀). –

+0

이 코드로 문제를 재현 할 수 없습니다. 그것은 나를 위해 올바르게 작동하지만 - 나는 윈도우를 사용하지 않고있다. – senderle

+0

Linux에서 CPython 2.7.3을 사용하여 예제를 시험해 보았습니다. – user1202136

답변

5

기본적으로 sr2222가 언급 한 내용은 정확합니다. multiprocessing manager docs에서 _____ainain 모듈은 어린이가 가져올 수 있어야한다고 말합니다. 각 관리자는 "개체는 생성 된 자식 프로세스에 해당합니다"이므로 각 자식은 기본적으로 모듈을 다시 가져옵니다 (모듈 범위에서 print 문을 내 고정 버전에 추가하여 볼 수 있습니다!) ... 무한 재귀가 발생합니다 .

하나의 해결책은 F1()로 관리 코드를 이동하는 것입니다 : 당신이 무엇을보고 원인 왜

import multiprocessing 
import logging 

def g1(results, x): 
    y = x*x 
    print "processing: y = %s" % y 
    results.append(y) 

def f1(): 
    logger = multiprocessing.log_to_stderr() 
    logger.setLevel(multiprocessing.SUBDEBUG) 
    manager = multiprocessing.Manager() 
    results = manager.list() 
    pool = multiprocessing.Pool(processes=4) 
    for (i) in range(0,15): 
     pool.apply_async(g1, [results, i]) 
    pool.close() 
    pool.join() 


def main(): 
    f1() 

if __name__ == "__main__": 
    main() 
+0

그것이 내가 시작한 곳입니다. 그러나 관리자와 결과를 f1에 두는 것은 g1에서 사용할 수 없음을 의미합니다. 하나는 NameError를 얻습니다. – bsdz

+0

@bsdz : 그것이 내가 (결과에)'결과를 통과 한 이유입니다. ...'manager'가 필요하다면 그것을 넘겨 줄 수도 있습니다. ... 또는 클래스를 만들어 인스턴스 수준에서 저장할 수 있습니다. – Gerrat

+0

아, 그래, 나는 그것을 놓쳤다. 나는 그것을 그렇게 전달하지 않아도되기를 바랬다는 것을 인정해야한다. 그러나 그것이 문서화 된 방법이다. 감사! – bsdz

관련 문제