2012-06-19 1 views
5

궁극적으로 내가 뭘하려고하는지 궁금해하는 것은 그 라인에있는 정보로 계산을 한 다음 결과를 일부 전역 객체에 추가하는 것입니다. 일하다. 예를 들어, 아래 코드에서 test는 항상 0입니다. 나는 이것이 틀렸다는 것을 알고 있으며, 다른 방법으로 시도해 보았지만 여전히 효과가 없다.파이썬에서 다중 처리를 할 때 전역 변수가 변하는 경우

import multiprocessing as mp 

File = 'HGDP_FinalReport_Forward.txt' 
#short_file = open(File) 
test = 0 

def pro(temp_line): 
    global test 
    temp_line = temp_line.strip().split() 
    test = test + 1 
    return len(temp_line) 

if __name__ == "__main__": 
    with open("HGDP_FinalReport_Forward.txt") as lines: 
     pool = mp.Pool(processes = 10) 
     t = pool.map(pro,lines.readlines()) 
+2

전역은 일반적으로 당신이 뭔가를 잘못하고있는 징조이다. 프로그램을 피하는 방법을 바꾸는 것이 좋습니다 - 장기적으로 두통을 덜어주고 더 좋은 방법이 항상 있습니다. –

+0

다중 처리 모듈의 요점은 동일한 프로세스에서 스레드가 아닌 자식 프로세스를 생성한다는 것입니다. 일반적으로 모든 상쇄 관계가 있습니다. 안타깝게도, 문서에서는 이러한 상반 ​​관계에 대해 설명하지 않습니다. 이미 알고 있다고 가정합니다. 문서의 "프로그래밍 가이드 라인"을 모두 따르면 이해하지 못할 수도 있지만 실제로 배워야합니다. – abarnert

답변

15

풀에서 생성 한 작업자 프로세스는 전역 변수의 복사본을 가져 와서이를 업데이트합니다. 명시 적으로 설정하지 않으면 메모리를 공유하지 않습니다. 가장 쉬운 해결책은 test의 최종 값을 주 프로세스로 다시 전달하는 것입니다. 반환 값을 통해. 같은 뭔가 (검증되지 않은) : 여기

def pro(temp_line): 
    test = 0 
    temp_line = temp_line.strip().split() 
    test = test + 1 
    return test, len(temp_line) 

if __name__ == "__main__": 
    with open("somefile.txt") as lines: 
     pool = mp.Pool(processes = 10) 
     tests_and_t = pool.map(pro,lines.readlines()) 
     tests, t = zip(*test_and_t) 
     test = sum(tests) 
+8

여기서 중요한 점은'멀티 프로세싱 '을 사용하면 스레드 (우물, 프로세스)가 상태를 공유하지 않는다는 것입니다. –

+2

+1, +1 @ 라티웨어. 나는 다중 처리 문서가 "쓰레딩 모듈과 유사한 API를 사용하여 프로세스를 산란하는"방법이 "쓰레드 생성"과 다른 점을 조금 더 명확히하기를 바란다 ... – abarnert

+0

그레이트 것들! 그것은 장고 모델을 업데이트하는 데 도움이되었습니다. 분명히 연결은 분기되지 않으며 다른 프로세스에 의해 부적절하게 닫힐 수 있습니다. 내가이 접근법을 사용했지만 zip을 사용하지 않았다는 것을 알고 싶으면, 그냥 for 루프를 사용하여 목록에서 튜플 요소에 액세스 한 다음 tuple_element [index]를 사용하여 튜플을 통과하는 각 목록 항목에 액세스했습니다. – radtek

0

은 멀티 내에서 전역 변수를 사용하는 예입니다.

우리는 각각의 프로세스 변수의 복사본으로 작동하는지 분명히 알 수 있습니다

import multiprocessing 
import time 
import os 
import sys 
import random 
def worker(a): 
    oldValue = get() 
    set(random.randint(0, 100)) 
    sys.stderr.write(' '.join([str(os.getpid()), str(a), 'old:', str(oldValue), 'new:', str(get()), '\n'])) 

def get(): 
    global globalVariable 
    return globalVariable 

globalVariable = -1 
def set(v): 
    global globalVariable 
    globalVariable = v 

print get() 
set(-2) 
print get() 

processPool = multiprocessing.Pool(5) 
results = processPool.map(worker, range(15)) 

출력 :

27094 0 old: -2 new: 2 
27094 1 old: 2 new: 95 
27094 2 old: 95 new: 20 
27094 3 old: 20 new: 54 
27098 4 old: -2 new: 80 
27098 6 old: 80 new: 62 
27095 5 old: -2 new: 100 
27094 7 old: 54 new: 23 
27098 8 old: 62 new: 67 
27098 10 old: 67 new: 22 
27098 11 old: 22 new: 85 
27095 9 old: 100 new: 32 
27094 12 old: 23 new: 65 
27098 13 old: 85 new: 60 
27095 14 old: 32 new: 71 
관련 문제