1

スレッド化されたコードを簡単にする方法を探しています。

私のコードには、次のようなことをする場所がたくさんあります。

for arg in array:
   t=Thread(lambda:myFunction(arg))
   t.start()

つまり、毎回異なるパラメーターに対してスレッドで同じ関数を実行します。

もちろん、これは実際のコードの単純化されたバージョンであり、通常、ループ内のコードforは 10 ~ 20 行の長さであり、上記の例のように 1 つの補助関数を使用して単純化することはできませんmyFunction(そうであった場合、スレッドプールを使用できたはずです)。

また、このシナリオは私のコードでは非常に一般的であるため、冗長だと思われる行がたくさんあります。この定型コードをすべて処理する必要がなく、代わりに次のようなことができれば、非常に役立ちます。

for arg in array:
      with threaded():
          myFunction(arg)

つまり、どういうわけかthreaded()その中のすべてのコード行を取得し、別のスレッドで実行します。

コンテキストマネージャーはそのような状況で使用することは想定されておらず、おそらく悪い考えであり、醜いハックが必要になることを知っていますが、それでも-それは可能で、どのように行うことができますか?

4

4 に答える 4

1

これはどう:

for arg in array:
    def _thread():
        # code here
        print arg

    t = Thread(_thread)
    t.start()

さらに、デコレータを使用すると、少し砂糖を加えることができます。

def spawn_thread(func):
    t = Thread(func)
    t.start()
    return t

for arg in array:
    @spawn_thread
    def _thread():
        # code here
        print arg
于 2010-06-26T16:58:32.587 に答える
0

あなたはそれを複雑にしすぎていると思います。これが私が使用する「パターン」です。

# util.py
def start_thread(func, *args):
    thread = threading.Thread(target=func, args=args)
    thread.setDaemon(True)
    thread.start()
    return thread

# in another module
import util
...
for arg in array:
    util.start_thread(myFunction, arg)

作成する必要があることについては大したことはわかりませんmyFunction。関数を開始する関数とインラインで関数を定義することもできます。

def do_stuff():
    def thread_main(arg):
        print "I'm a new thread with arg=%s" % arg
    for arg in array:
        util.start_thread(thread_main, arg)

多数のスレッドを作成している場合は、スレッドプールの方が間違いなく理にかなっています。Queueおよびthreadingモジュールを使用して、簡単に独自のものを作成できます。基本的に、jobsキューを作成し、Nワーカースレッドを作成し、各スレッドにキューへの「ポインター」を与え、キューからジョブをプルして処理させます。

于 2010-06-26T14:07:04.507 に答える
0

ここでスレッドプールが役に立ちますか? Python の多くの実装が存在します。たとえば、これです。


PS:正確なユースケースが何であるかを知りたい

于 2010-06-26T12:45:21.190 に答える
0

必要なのは、一種の「コンテキストスレッドプール」です。

あなたが与えた方法と同様に使用するように設計された、このモジュールの ThreadPool クラスを見てください。使用は次のようになります。

with ThreadPool() as pool:
    for arg in array:
        pool.add_thread(target=myFunction, args=[arg])

ThreadPool に指定されたタスクが失敗すると、エラーのフラグが立てられ、標準のエラー バックトレース処理が実行されます。

于 2010-06-26T12:48:05.880 に答える