2017-03-14 7 views
1

私は、ここにいる誰かが私を助けてくれることを望んでいるという単純な問題があります。 forループを介して一連のスレッドとして呼び出される関数があります。配列出力はQueueに格納され、メインプログラムで取得されます。スレッドは完璧に機能しますが、残念ながらデータの配列は呼び出された順序とは異なる順序で返されます。私はこの疑問に疑似コードの例を取り上げています。スレッドが作成されて並列に実行されるが、作成された順に返されるスレッドロックメカニズムがあるかどうか。スレッドが作成された順に返されるようにする

import numpy as np 
from multiprocessing import Process, Queue 

def Thread_Func(container1,container2,container3,iterable,more_parameters, \ 
       Thread): 
    Array1 = np.array([]); Array2 = np.array([]) 
    for i in range(len(iterable)): 
     Array1 = np.append(some_operation) 
     Array2 = np.append(some_other_operation) 
    container1.put(Array1) 
    container2.put(Array2) 
    container3.put(Thread) 

if __name__ == "__main__": 
    container1 = Queue() 
    container2 = Queue() 
    container3 = Queue() 
    Thread = 1 
    for index in range(Number_of_Threads): 
     p = Process(target=Thread_Func,args=(container1,container2,container3, \ 
        iterable,more_parameters)) 
     Thread = Thread + 1 
     p.daemon = True 
     p.start() 

    Array1  = np.array([]) 
    Array2  = np.array([]) 
    Thread_Array = np.array([]) 
    for index in range(Number_of_Threads) 
     Array1 = np.append(Array1,container1.get()) 
     Array2 = np.append(Array2,container2.get()) 
     Thread_Array = np.append(Thread_Array,container3.get()) 
    p.join() 

    print (Array1) 
    print (Array2) 
    print (Thread_Array) 

それはスレッドが順不同で返されたArray1のプリントアウトを見た後にかなり明白ですが、私は2つのスレッドを実行した後Thread_Arrayを見たとき、私は[1. 2.]を見るべきであるとき、私は、[2. 1.]を参照してください。スレッドが正しい順序で返されるようにするためにできることはありますか?

+0

スレッドNUMの順序はここで重要なのはなぜ?私は、最初のスレッドの実行が非常に長く、他のスレッドがそれを待たなければならないと仮定すると、シングルスレッドの方法に戻ってくるかもしれないので、そうは思わない...スレッドnumリストの並べ替えはどうですか? – linpingta

+0

実際に。 'numpy'は方程式から完全に削除することができ、例はずっと簡単になります。プロセス作成で 'スレッド 'が渡されないのはなぜですか? –

+0

そして、これをしようとしている理由を説明してください。 – Soviut

答えて

0

マルチプロセッシング。あなたが必要とするような音が聞こえます。デフォルトでは、システム内のプロセッサ数に等しいプールを作成します。仕事を提出し、将来の結果を提出された順序で配列に格納し、必要な順番で結果を得ることができます。

例:

from multiprocessing import Pool 
import time 
import random 

# Use a simple list of numbers for work 
work = list(range(100)) 

# Run jobs in size of chunk. 
chunk = 10 

random.seed(time.time()) 

# This work is so simple we'll sleep to simulate longer work calculations 
# and the threads will finish in random order. 
def worker(arr): 
    time.sleep(random.randint(1,5)/20) # .05 to .25 seconds 
    return [x*10 for x in arr] 

if __name__ == '__main__': 
    pool = Pool() 
    results = [] 

    # Break the work into chunks, and submit jobs to run asynchronously. 
    # The callback will print the index of the job as it finishes. 
    for i in range(0,len(work),chunk): 
     results.append(pool.apply_async(
      worker, 
      args=(work[i:i+chunk],), 
      callback=lambda x,i=i:print(i))) 

    # Fetch the results in the order submitted. 
    for result in results: 
     print(result.get()) 

は、スレッドがアウト・オブ・オーダー終了したことを確認します。完了した最初の結果をフェッチすると、結果は完了したジョブまで順番に印刷されます。その後、再び50ストロークが終わるのを待ってストールした。

出力:

10 
30 
20 
40 
0 
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90] 
[100, 110, 120, 130, 140, 150, 160, 170, 180, 190] 
[200, 210, 220, 230, 240, 250, 260, 270, 280, 290] 
[300, 310, 320, 330, 340, 350, 360, 370, 380, 390] 
[400, 410, 420, 430, 440, 450, 460, 470, 480, 490] 
80 
90 
70 
60 
50 
[500, 510, 520, 530, 540, 550, 560, 570, 580, 590] 
[600, 610, 620, 630, 640, 650, 660, 670, 680, 690] 
[700, 710, 720, 730, 740, 750, 760, 770, 780, 790] 
[800, 810, 820, 830, 840, 850, 860, 870, 880, 890] 
[900, 910, 920, 930, 940, 950, 960, 970, 980, 990] 
関連する問題