2016-10-09 6 views
0

私のenvは非常にfuzzedです、私は私のapply_async(TEST_FUNC)を実行し、私はTEST_FUNCのような現在のprocess_name.As印刷してみましょうPython2.7.Iです:なぜpool.apply_async()によって生成されたサブプロセスが常にMainProcessとして実行されますか?

q = Queue(maxsize=20) #multiprocessing.Queue 

def test_func(queue): 
    print 'Process' 
    print multiprocessing.current_process() 

if __name__ == '__main__': 
    pool = Pool(processes=3) 
    for i in xrange(3): 
     pool.apply_async(test_func(q,)) 
    while True: 
     time.sleep(1) 
     if q.empty(): 
      break 
     print 'Main Process Monitoring' 
     print multiprocessing.current_process() 

コードは何の構文エラーを持っていないし、そしてターミナルは常に、なぜapply_async()ができるよう、私は理解することはできません..私は​​を変更した場合、それは単にforループを終了し、そしてそれだけで'Main Process Monitoring' <MainProcess>を印刷と同じように、test_funcに入ることができませんでした

<MainProcess>

を印刷しますそれは正常に動作し、動作すると動作しますMainProcessとして、私はpool.close(),pool.join()を試しました。何も変わりません。 誰かが助けることができれば。たくさんありがとう!

答えて

1

まず、あなたのtest_func機能は、何return文を持っていない。これは意味

>>> import multiprocessing 
>>> x = test_func(None) 
Process 
<_MainProcess(MainProcess, started)> 
>>> print x 
None 

こと:

pool.apply_async(test_func(q,)) 

は引数付きのtest_funcを呼び出します(q,)、これはNoneを返します。 Nonepool.apply_asyncに渡します。

The multiprocessing documentationは、最初の引数ラapplyを呼び出すようapply_asyncを説明しますが、非同期、すなわち、その結果を待たず。ちょうどそれが何をするか確認するために、対話的にapply(None)を試してみましょう:

>>> apply(none) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: 'NoneType' object is not callable 

だから我々は、我々がしようとするまでは、それが何をするかですが、エラーが延期されていることを、apply_asyncは例外TypeError-、実際に調達するために期待するかもしれません結果が得られます。

>>> pool = multiprocessing.Pool(processes=3) 
>>> pool.apply_async(None) 
<multiprocessing.pool.ApplyResult object at 0x801b27510> 

は(特別な名前_が対話中に返された最新の値を保持している)私たちはそれを使用して調べることができそれでは、このApplyResultオブジェクトをつかむしてみましょう:

>>> x = _ 

非同期は私たちのために結果を持って適用する場合は今、私たちが見ることができます:

>>> x.ready() 
True 

それがありません! (もしそうでなければx.wait()を呼び出すことができますが、準備が整っていますので、これを押してください)結果は通常の値ですか、例外ですか?

>>> x.successful() 
False 

ああ、結果は例外です。 apply_asyncからNoneが(後にすべての機能ではない)機能Noneの実行をオフにスピン、そして私たちは、最終的な結果を収集した後渡し:

>>> x.get() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/local/lib/python2.7/multiprocessing/pool.py", line 567, in get 
    raise self._value 
TypeError: 'NoneType' object is not callable 

そしてそこに我々は答えを持っている:の例外を取得してみましょう結果は我々が期待する例外です。

私は(カンマを追加)pool.apply_async(test_func,(q,))を変更した場合、それはtest_funcに入ることができませんでした...

はのは、対話インタプリタにそのような何かを試してみましょう。私は qありませんが、 test_funcが実際にその引数を使用していないので、我々は渡しなしで、ここでOKだ:

>>> x = pool.apply_async(test_func, (None,)) 
>>> Process 
<Process(PoolWorker-2, started daemon)> 

この出力は少し厄介ですが、それが働いたように、それは確かに見えます。 xが結果を持っている場合を見てみましょう、それが成功したのかどうか、そしてどのようなその結果は次のとおりです。

x.ready() 
True 
>>> x.successful() 
True 
>>> x.get() 
>>> 

(最初>>>プロンプトが欠けているように見えるが、それは本当にただのプリントオーバーされていますtest_funcで印刷の事で)。成功した価値はありますが、それはNoneなので、通訳者はここで何も印刷しませんでした。それを見るにはprint x.get()をしなければなりませんでした。言い換えれば

、あなたは(1)どこかスピンオフ「保留中の結果を」保存し、(2)実際に結果を取得するために.get()を使用する必要がありますapply_async使用するつもりなら。また、関数から何かを返す必要があります。

一方、このループ:あなたのキューオブジェクトqあなたはそれをテストする際に空あるので、それのうち、あなたがすぐにbreakので

while True: 
    time.sleep(1) 
    if q.empty(): 
     break 
    print 'Main Process Monitoring' 
    print multiprocessing.current_process() 

は、一度を通じてすべての方法を実行されることはありません。

+0

私のキューオブジェクト 'q'は空ではありません。いくつかのsteps.Myプログラムは結果を返すためにサブプロセスを必要とせず、return文を追加する必要がありますか?あなたの示唆。 – Doe

+0

実際の関数に有用な戻り値がない場合、それを収集する必要はありませんが、それが完了するのを待つ必要があるかもしれません。しかし、Queueオブジェクト 'q'に入るデータを取り除いた場合、おそらく他の実際の問題を取り除いたでしょう。 – torek

+0

ありがとう、私は戻り値と.get()を使用して、多くの助けを見つけた。例外 'を発生させる 'result = pool.apply_async(test_func、(q))' print result.get() '継承を介してプロセス間でのみ共有されます。 'p = Process(target = test_func、args =(q、))'のようにすれば、正常に動作します。 – Doe

0

時々、私はapply_async(test_func, (i,))を使用すべきであることを知りますが、これは私の間違いです。

しかし、私がapply_async(test_func, (q,))を使用した場合、それは動作しません。qはマルチプロセッシングです.Queue()。キューオブジェクト以外の他のものを削除または置換すると正常に処理されます)

私はキューがいくつかのエラーまたは他の何か提起を持っているかどうかわからない...

は、いずれかのことを知っていますか?どうもありがとう!対話的なPythonにこれを挿入する

def test_func(queue): 
    print 'Process' 
    print multiprocessing.current_process() 

:それはNoneを返すよう

関連する問題