2017-10-04 29 views
0

私は基本的に無限ループを実行しているコードを持っており、ループの各反復でいくつかの命令を実行します。これらの命令の中には、マルチプロセッシングを使って行う「並列」で実行するものがあります。Python:無限ループ内のマルチスレッド

from multiprocessing import Pool 
from multiprocessing.dummy import Pool as ThreadPool 

def buy_fruit(fruit, number): 
    print('I bought '+str(number)+' times the following fruit:'+fruit) 
    return 'ok' 

def func1(parameter1, parameter2): 
    myParameters=(parameter1,parameter2) 
    pool= Threadpool(2) 
    data = pool.starmap(func2,zip(myParameters)) 
    return 'ok' 

def func2(parameter1): 
    print(parameter1) 
    return 'ok' 



while true: 
    myFruits=('apple','pear','orange') 
    myQuantities=(5,10,2) 
    pool= Threadpool(2) 
    data = pool.starmap(buy_fruit,zip(myFruits,myQuantities)) 
    func1('hello', 'hola') 

私はメインループ内のマルチプロセスを持っているので、それは、少し厄介だ同意するだけでなく、関数内:ここに私のコードの構造の一例です。

ループが数分を実行し、私はエラーを取得するまで、それですべてが、うまく機能: 「はRuntimeError:新しいスレッドを起動することはできません」

を、私はこれは私が持っているという事実によるものであることを、オンラインで見ましたスレッドが多すぎます。

各ループの終了までにすべてのスレッドを閉じる最も簡単な方法は何ですか?新しいループの反復の開始時に「フレッシュ」を再開できますか?

お時間をいただきありがとうございます。

ベスト、 ジュリア

PS:コード例は一例であり、私の本当の機能は、各ループの中で多くのスレッドを開き、各機能を実行するために数秒かかります。

+3

プールの_join()_機能を見て、これは、あなたがループの外スレッドプールを作成することもできます – Minato

+0

探しているものかもしれません。 CPUバインドされたスレッドのコンテキストで_globalインタプリタlock_を読んでみてください。 – moooeeeep

答えて

0

ループの最後にスレッドを終了していないため、新しいThreadPoolオブジェクトがエンドレスループ内に作成されている可能性があります。無限ループの外でオブジェクトを作成しようとしましたか?何らかの理由でご利用の場合は、各ループの反復で新しいThreadPoolのオブジェクトを作成する必要があれば

pool = ThreadPool(2) 
while True: 
    myFruits = ('apple','pear','orange') 
    myQuantities = (5,10,2) 
    data = pool.starmap(buy_fruit, zip(myFruits,myQuantities)) 

代わりに、そしてあなたの質問に答えるために、ContextManager(with表記)は、すべてのスレッドが去る時に閉じられていることを確認するために使用しますContextManager。

while True: 
    myFruits = ('apple','pear','orange') 
    myQuantities = (5,10,2) 
    with ThreadPool(2) as pool: 
     data = pool.starmap(buy_fruit, zip(myFruits,myQuantities)) 

注目すべき性能差は、上記のコードと比べて顕著です。スレッドの作成と終了はコストがかかります。そのため、上記の例ははるかに高速に動作し、おそらく使用したいものです。

「ネストされたThreadPools」を含む編集について:私はあなたのThreadPoolの1つのインスタンスを維持し、必要に応じてネストされた関数への参照を渡すことをお勧めします。

def func1(pool, parameter1, parameter2): 
    ... 
... 

pool = ThreadPool(2) 
while True: 
    myFruits=('apple','pear','orange') 
    myQuantities=(5,10,2) 
    data = pool.starmap(buy_fruit, zip(myFruits,myQuantities)) 
    func1(pool, 'hello', 'hola') 
+0

こんにちは、ありがとうございます。さて、メインループの外側にプールを作成することをお勧めします。問題は、私のコードがもう少し複雑で、メインループの中で関数を呼び出すことです。関数にはマルチスレッドも含まれています(最初の質問を編集しました)。スレッドを終了する方法はありますか?重要なのは、できるだけ同期して機能を実行することだけです。実行中のすべてのスレッドを閉じるためにメインループの最後を待つ必要はありません。ありがとう! –

+0

ちょっと@JuliaScivi。私はあなたが "スレッドを終了する"ということをどういう意味かはっきりしていません。ここで使用している 'ThreadPool'クラスは、スレッドの数を維持し、(.starmap'のように)これらのスレッドに作業をプッシュする手段を提供するように設計されています。他の関数から 'ThreadPool'に作業をプッシュできるようにしたいのであれば、その関数への参照を渡すだけです。同期した操作( 'starmap')のみを使用しているため、作業は同期的に実行されます。私の答えを編集して、私が意味することを説明しました –