2012-06-19 29 views
5

所以我最終要做的就是讀一行,用該行中的信息做一些計算,然後將結果添加到某個全局對象,但我永遠無法得到它上班。例如,在下面的代碼中,測試總是爲0。我知道這是錯誤的,我嘗試過其他方式,但它仍然無法正常工作。在python中多處理時改變全局變量

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

這裏關鍵的是,使用'multiprocessing',線程(以及進程)不共享狀態。 –

+2

+1爲答案,+1 @Lattyware。我希望多處理文檔對於「使用類似於線程模塊的API的產卵過程」與「創建線程」有什麼不同,因爲這樣可以解決模塊在SO上的一半問題...... – abarnert

+0

好東西!它幫助我更新django模型。顯然,連接不是分叉的,可以被另一個進程不正確地關閉。爲了照顧我使用這種方法,但我沒有使用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