2012-06-19 12 views
5

私は最終的には行を読み、その行の情報を使っていくつかの計算を行い、その結果をいくつかのグローバルオブジェクトに追加しますが、働くたとえば、以下のコードではtestは常に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を使用したプロセスの生成方法が「スレッドの作成」とどのように異なるのかを少しはっきりさせたいと思っています。 – 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 
関連する問題