2016-04-02 2 views
2

私は、関数から結果を収集するために使用するリストがプロセスによって更新されないマルチプロセッシングの状況があります。私はコードの2つの例を持っています。リストを更新するものがあります。修正:コードは 'Thread'を使って正しく更新されますが、 'Process'を使用すると失敗します。とそうではありません。私はどんな種類のエラーも検出できません。私はこれが私が理解していない範囲の微妙なものかもしれないと思う。ここでマルチプロセッシングスコープ: 'マルチプロセッシングプロセス'を使用して更新しません。 'threading.Thread'を使用して処理しました


は実施例である:訂正:この例では、いずれかの動作しません。しかし、threading.Threadで動作します。ここで

def run_knn_result_wrapper(dataset,k_value,metric,results_list,index): 
    results_list[index] = knn_result(dataset,k_value,metric) 

results = [None] * (k_upper-k_lower) 
threads = [None] * (k_upper-k_lower) 
joined = [0] * (k_upper-k_lower) 

for i in range(len(threads)): 
    threads[i] = Process(target=run_knn_result_wrapper,args=(dataset,k_lower+i,metric,results,i)) 
    threads[i].start() 
    if batch_size == 1: 
     threads[i].join() 
     joined[i]=1 
    else: 

     if i % batch_size == batch_size-1 and i > 0: 
      for j in range(max(0,i - 2),i): 
       if joined[j] == 0: 
        threads[j].join() 
        joined[j] = 1 
for i in range(len(threads)): 
    if joined[i] == 0: 
     threads[i].join() 


Ignoring the "threads" variable name (this started on threading, but then I found out about the GIL), the `results` list updates perfectly. 

結果リストが更新されないコードです:

def prediction_on_batch_wrapper(batchX,results_list,index): 
     results_list[index] = prediction_on_batch(batchX) 



batches_of_X = np.array_split(X,10) 

overall_predicted_classes_list = [] 
for i in range(len(batches_of_X)): 
    batches_of_X_subsets = np.array_split(batches_of_X[i],10) 
    processes = [None]*len(batches_of_X_subsets) 
    results_list = [None]*len(batches_of_X_subsets) 
    for j in range(len(batches_of_X_subsets)): 
     processes[j] = Process(target=prediction_on_batch_wrapper,args=(batches_of_X_subsets[j],results_list,j)) 
    for j in processes: 
     j.start() 
    for j in processes: 
     j.join() 
    if len(results_list) > 1: 
     results_array = np.concatenate(tuple(results_list)) 
    else: 
     results_array = results_list[0] 

Pythonのスコープはresults_listリストはprediction_on_batch_wrapper機能によって更新されません規則の範囲内私は、なぜ言うことができません。

デバッグセッションがprediction_on_batch_wrapper関数の中results_list値は、実際には、更新さないことを明らかに...何とか、それはスコープのこの第二のpythonファイルにローカルであり、第1のグローバル...


ここでは何が起こっていますか?

+1

スレッドとプロセスの違い、およびあなたが言及した質問の答えに '' manager = Manager() ''と '' return_dict = manager.dict() ''を使用する理由を理解していますか? :http://stackoverflow.com/questions/10415028/how-can-i-recover-the-return-value-of-a-function-passed-to-multiprocessing-proce – minhhn2910

+0

いいえ、まったくありません:)しかし、私は今私がすると思います。 – bordeo

+0

'' manager = Manager() ''と '' results_list = managerを試してください。まだプロセスを使用したい場合は、リスト([None] * len(batches_of_X_subsets)) ''を2番目のスニペットに追加してください:D – minhhn2910

答えて

2

これは、別のプロセスを作成しているためです。別のプロセスはリソースを共有せず、メモリも含まれています。

各プロセスは独立した独立した実行中のプログラムで、通常はタスクマネージャーまたはpsに表示されます。 Processを使用して追加のプロセスを開始すると、プロセスを起動するときに2番目のPythonインスタンスが起動するはずです。

スレッドは、メインプロセス内の別の実行ポイントであり、メインプロセスのすべてのリソースを複数のコアにわたって共有します。プロセス内のすべてのスレッドは、プロセス全体のどの部分も見ることができますが、どれくらい使用できるかは、スレッド用に記述したコードと記述する言語の制限によって決まります。

Processを使用することは、プログラムの2つのインスタンスを実行するようなものです。新しいプロセスにパラメータを渡すことができますが、それらはパスされても共有されなくなります。たとえば、メインプロセス内のデータを変更した場合、2つのプロセスが完全に別個のデータのコピーを持っているため、新しいプロセスは変更を認識しません。

データを共有する場合は、実際にプロセスではなくスレッドを使用する必要があります。ほとんどのマルチプロセッシングのニーズでは、厳密な分離が必要な場合を除いて、スレッドがプロセスよりも望ましいです。

+0

メモリを割り当てて、リターンオブジェクトを出力するためにramに座標を与えましたか?それはPythonで可能ですか? – bordeo

+0

いいえ。座標が別のプロセスからアクセスできないためです。名前付きパイプなどを使用することもできますが、それはあなたのコードをかなり複雑にするでしょう。なぜスレッドではなくプロセスを使用したいのですか? –

+0

あなたが提供するプロセスの例のリンクは情報と一致しています。この例では、生成された各プロセスから値を読み取ることはなく、生成された各プロセスにデータを渡し、生成したプロセスが出力し、追加のデータを検索することなく(例えば、iの更新値がない場合) –

関連する問題