どのようにマルチプロセッシングが正しく行われたかを知りたい。私がQueue
(左の緑色の丸)に書かれている関数f1
によって生成されたリスト[1,2,3,4,5]
を持っていると仮定します。今度は、そのキューから2つのプロセスを引き出します(プロセス内でf2
を実行します)。彼らはデータを処理します。例えば、値を倍にして2番目のキューに書き込みます。今、関数f3
はこのデータを読み取り、それを印刷します。機能インサイドパイプラインでのマルチプロセッシングが正しく行われた
は永遠にキューから読み取るしようとし、ループのようなものがあります。どのようにこのプロセスを止めるのですか?
アイデアは、1
f1
リストだけを送信するのではなく、またNone
オブジェクトまたはcustonオブジェクト、class PipelineTerminator: pass
またはちょうどダウンすべての方法を伝播されているいくつかのように。 f3
は、None
が来るのを待っています。そこにいるとき、ループから壊れます。問題:f2
の2つのうちの1つがNone
を読み取って伝播し、もう1つがまだ番号を処理している可能性があります。最後の値は失われます。 2
f3
アイデアf1
です。したがって、関数f1
はデータとパイプを生成し、プロセスをf2
で生成し、すべてのデータをフィードします。産卵と給餌の後、それは受信したオブジェクトを数えて処理するだけで、2番目のパイプで待機します。どのくらいのデータが供給されているか知っているので、f2
を実行しているプロセスを終了できます。しかし、目標が処理パイプラインを設定することであれば、異なるステップは分離可能でなければならない。したがって、f1
,f2
およびf3
は、パイプラインの異なる要素であり、高価な手順は並行して行われます。
アイデア3
パイプラインの各部分が関数であるそれが好きで、それらを管理する責任があるとして、この関数は、プロセスを生成。それは、どのくらいのデータが入ってきたか、どのくらいのデータが返されたかを知っています(yield
かもしれません)。したがって、None
オブジェクトを伝播することは安全です。
setup child processes
execute thread one and two and wait until both finished
thread 1:
while True:
pull from input queue
if None: break and set finished_flag
else: push to queue1 and increment counter1
thread 2:
while True:
pull from queue2
increment counter2
yield result
if counter1 == counter2 and finished_flag: break
when both threads finished: kill process pool and return.
(代わりにスレッドを使用しての、多分1は賢く解決策を考えることができます。)
そう...
私は供給し、待っている、アイデア2次ソリューションを実装しています結果は到着するが、実際には独立した機能を持つパイプラインではなかった。それは私が管理しなければならなかった仕事のために働いたが、維持することは難しかった。
パイプラインをどのように実装するのか(複数のプロセスで1つのプロセスで簡単にジェネレータの機能を使用するなど)を聞いて、通常はそれらを管理しています。
しかし、 'f2' *の労働者は、それが最後のことをどのように知っていますか? 'f1'はそこにいる作業者の数を知り、その数のカスタムオブジェクトを送る必要があります。このようにして、すべての作業者がこの通知を受け取ることが保証されます。それは明らかに可能ですが、私は "関数を単にプラグインする"ことはできません、私は各ステップに何人の労働者がいるか知る必要があります。だからこそ私はアイデア3が好きです。そして、私には初めてのことです。私はそれを掘り下げていきます。 –
それは私が "受け入れ"をチェックした理由です:) –
"作業停止"カスタムオブジェクトは "F1"によって送信されるので、 "f2"ワーカープロセスの総数を含めることができます。これらが "作業停止"オブジェクトを "f3"に渡すだけであれば、作業者の総数を知ることができます。より多くの情報がこの方法で送信される可能性があります。重要なことは、少なくとも「f3」(ただしおそらくは「f1」)でも「コントロールレイヤー」を持つことです。実際に処理されるキュー上のオブジェクト – jsbueno