2017-05-01 8 views
0

別の関数で辞書clean_txt内のリストを操作しようとしていますが、機能していないため、空リストが辞書内にあります。変数を別の関数内の関数にローカルで変更できません

リストと辞書の両方が可変オブジェクトなので、ここで何が問題なのですか?

def process_questions(i, question_list, questions, question_list_name): 
    ''' Transform questions and display progress ''' 
    print('processing {}: process {}'.format(question_list_name, i)) 
    for question in questions: 
     question_list.append(text_to_wordlist(str(question))) 

@timeit 
def multi(n_cores, tq, qln): 
    procs = [] 
    clean_txt = {} 
    for i in range(n_cores): 
     clean_txt[i] = [] 

    for index in range(n_cores): 
     tq_indexed = tq[index*len(tq)//n_cores:(index+1)*len(tq)//n_cores] 
     proc = Process(target=process_questions, args=(index, clean_txt[index], tq_indexed, qln,)) 
     procs.append(proc) 
     proc.start() 

    for proc in procs: 
     proc.join() 

    print('{} records processed from {}'.format(sum([len(x) for x in clean_txt.values()]), qln)) 
    print('-'*100) 

答えて

1

スレッドはプロセスではありません。

プロセスが作成されると、プログラムのメモリがコピーされ、各プロセスが独自のセットで動作するため、は共有されません。です。

ここにあなたが理解するのに役立ちます質問です:Multiprocessing vs Threading Python

あなたはプロセス間のメモリを共有したい場合は、semaphoresに見て、またはその代わりThreadsを使用する必要があります。キューやデータベースなど、データを共有するための他のソリューションもあります。

1

異なるプロセスからclean_txt[index]に追加しています。 clean_txt[index]はそれを作成したメインのpythonプロセスに属します。プロセスは他のプロセスのメモリにアクセスしたり変更したりすることができないため、追加することはできません。 (実際はありません。以下の編集を参照してください)

共有メモリを作成する必要があります。

あなたはこの

from multiprocessing import Manager 
manager = Manager() 
... 
    clean_txt[i] = manager.list() 

のようなものが今、あなたは他のプロセスでは、このリストに追加することができ、共有メモリを作成するためにManagerを使用することができます。

編集からclean_txtについて

私の説明が明確ではありませんでした。 @Mareshに感謝します。

新しいProcessが作成されると、メモリ全体がコピーされます。したがって、新しいプロセスでリストを変更しても、メインプロセスのコピーには影響しません。だから共有メモリが必要です。

+0

親プロセスに属していると言うのは間違いです:) – Maresh

+0

@Maresh彼はメインプロセスで 'clean_txt [i] = []'を実行していますので、そのリストはメインプロセスの権利に属しますか? –

+0

それぞれのプロセスは、親プロセスのものからコピーされた独自のメモリ空間を持ちます。マルチプロセッシングで遊ぶときは、それを理解することが重要です。最後にあなたは正しいです、この正確なメモリアドレスは親に属しますが、IMOの説明ではっきりしているはずです。 – Maresh

関連する問題